Dart 변수 선언 / 할당
var
void main(){
/* var
* js의 var와 비슷, 어떤 타입의 컨텐츠도 할당할 수 있음
* 선언과 동시에 값을 할당하는 경우, dart는 해당 변수의 타입을 고정함.
* 선언과 동시에 할당하지 않은 경우, 어떠한 데이터 타입도 저장할 수 있는 Dynamic Type 변수
* */
var name = 'dylan';
var num = 1;
var dynamic; //Dynamic Type 변수
print(name.runtimeType); //String 타입
print(num.runtimeType); // int 타입
}
integer / double
void main(){
int num1 = 2; // int
double num2 = 0.5; // double
}
boolean
void main(){
bool isTrue = true; // boolean
}
String
void main(){
String name = 'dylan';
String job = 'engineer';
print(name + job); dylanengineer
print('$name is $job'); dylan is engineer
print('${name} is ${job}'); dylan is engineer
}
Dynamic
void main(){
/*
* var vs dynamic
* runtimeType을 보면 var 와 동일하게 String
* dynamic 으로 값이 할당되면, 재할당시 타입과 상관없이 변경 가능
* */
dynamic name = 'dylan';
var name1 = 'dylan';
name = 1; // dynamic 으로 선언/할당되면 다른 타입으로 변경 가능
name1 = 1; // var로 선언/할당되면 타입이 고정되어 다른 타입으로 변경 불가(에러 발생)
print(name.runtimeType);
print(name1.runtimeType);
}
nullable, non-nullable, null
void main(){
/*
* nullable - null이 될 수 있다.
* non-nullable - null이 될 수 없다.
* */
String name = 'Dylan';
name = null; //error
String? name2 = 'Dylan'; // 물음표를 붙이면 null 까지 들어갈 수 있는 데이터 타입을 의미한다.
print(name2!); // 느낌표를 붙이면 현재 이 변수는 null 이 아니라는 것을 의미한다.
}
final, const
void main(){
final String name = 'Dylan'; // final 을 쓰면, 변수의 값을 변경할 수 없다.
name = 'change the name'; // error
const String name2 = 'Dev'; // const 도 변수의 값을 변경 할 수 없다.
name2 = 'change the name2'; //error
final team = 'DevOps'; // const나 final 을 쓰면 타입 생략 가능(var 역할을 해줌)
/* final vs const */
final DateTime now = DateTime.now(); // error :: build 되는 시점에 값을 몰라도 됨
const DateTime now2 = DateTime.now(); // error :: build 되는 시점에 값을 알고 있어야함 (DateTime은 코드가 실행되는 시점의 시간을 가져오기때문에)
}
List
void main() {
/*
* generic 기호를 사용하여 내부 데이터의 데이터 타입 정의
* */
List<String> numList = ['일', '이', '삼', '사', '오'];
List<int> numList2 = [1, 2, 3, 4, 5];
List<dynamic> mixedList = ['일', 2, '삼', 4, '오']; // 여러 데이터 타입 데이터를 포함하고 싶은 경우
var mixedList2 = ['일', 2, '삼', 4, '오'];
print(mixedList);
print(mixedList2);
numList.add('육'); // data append
numList2.remove(5); // data remove
numList.indexOf('일'); // 0
}
Map
void main() {
/*
* 일반적인 Object를 dart에서는 Map 으로 표현
* */
Map<String, String> dictionary = {
// generic에 key value 의 데이터 타입을 각각 기입. 혹시 타입을 특정할 수 없다면 dynamic
'Harry Potter': '해리포터',
'Ron Weasley': '론 위즐리',
'Hermione Granger': '헤르미온느 그레인저'
};
Map<String, dynamic> test = {'integer': 1, 'String': '일'};
Map<String, bool> isHarryPotter = {
'Harry Potter': true,
'Ron Weasley': true,
'Ironman': false,
};
isHarryPotter.addAll({
// Map에 데이터 append
'Spiderman': false,
});
print(isHarryPotter['Ironman']); // key로 value 추출 가능
isHarryPotter['Hulk'] = false; // 임의적으로 추가 가능
isHarryPotter['Spiderman'] = true; // 값 변경 가능
isHarryPotter.remove('Harry Potter'); // 값 삭제 가능
print(isHarryPotter.keys); // key값들 추출가능
print(isHarryPotter.values); // key값들 추출가능
}
Set
void main() {
/*
* List와 아주 유사하나 List은 중복값이 들어갈 수 있고, Set은 중복값이 들어갈 수 없다
* 중복을 자동으로 처리해줌.
* */
final Set<String> names = {
'dylan',
'Flutter',
'Engineer',
'dylan',
};
print(names); //{dylan, Flutter, Engineer}
names.add('test'); // 값 추가
names.remove('test'); // 값 제거
print(names.contains('dylan')); //true
}
enum
/*
* enum을 쓰는것은 정의된 타입만 사용할 수 있게 강제하기 위함이다.
* string으로 비교하면 오타가 날 수 있고, 가독성이 떨어짐
* */
enum Status {
approved,
pending,
rejected,
}
void main() {
Status status = Status.pending;
if(status == Status.approved) {
print('승인');
}else if( status == Status.pending){
print('대기');
}else {
print('거절');
}
}
typedef
void main() {
int result = calculate(10, 20, 30, add);
print(result);
}
typedef Operation = int Function(int x, int y, int z);
// 더하기
int add(int x, int y, int z) => x + y + z;
int subtract(int x, int y, int z) => x - y - z;
int calculate(int x, int y, int z, Operation operation) => operation(x, y, z);
함수 / 파라미터 종류 / return type
void main() {
int sum = addNumbers(1, 2, 3);
int sum1 = addNumbersOption(1);
int sum2 = addNumbersNamed(y: 10, x: 20, z: 30);
int sum3 = addNumbersNamedOption(x: 10, y: 20);
int sum4 = addNumbersNamedPostional(10, y: 20, z: 30);
}
// positional parameter - 순서가 중요한 파라미터
int addNumbers(int x, int y, int z) {
int sum = x + y + z;
return sum;
}
// optional parameter - 파라미터가 필수가 아닐땐 []괄호사용
// null 값이 들어갈 수 있도록 데이터 타입에 ? 붙여줘도됨.
// 파라미터를 받을때 필수가 아니라면, 기본값을 넣어주자
int addNumbersOption(int x, [int y = 0, int z = 0]) {
int sum = x + y + z;
return sum;
}
// named parameter - 이름이 있는 파라미터 (순서가 중요하지 않음)
// 모든 파라미터가 필수일 경우
int addNumbersNamed({
required int x,
required int y,
required int z,
}) {
int sum = x + y + z;
return sum;
}
// named parameter - 이름이 있는 파라미터 (순서가 중요하지 않음)
// 파라미터가 필수가 아닐 경우
int addNumbersNamedOption({
required int x,
required int y,
int z = 30,
}) {
int sum = x + y + z;
return sum;
}
// named parameter와 positional parameter 을 같이 사용
int addNumbersNamedPostional(
int x, {
required int y,
required int z,
}) {
int sum = x + y + z;
return sum;
}
// 모든 데이터 타입을 리턴할 수 있다.
Map returnMa() {
Map<String, String> mapSample = {'name': 'dylan'};
return mapSample;
}
arrow function
void main() {
int sum = addNumber(10, y: 20, z: 30);
}
// arrow function
// syntax : returnType functionName(parameters...) => expression;
int addNumber(
int x, {
required int y,
required int z,
}) =>
x + y + z;
비교 연산
void main(){
int number1 = 1;
print(number1 is int); //true
print(number1 is String); //false
print(number1 is! int); // false
print(number1 is! String); // true
}
Loop
void main() {
int total = 0;
List<int> numbers = [1, 2, 3, 4, 5, 6];
for (int i = 0; i < numbers.length; i++) {
total += numbers[i];
}
total = 0;
for (int number in numbers) {
total += number;
}
total = 0;
while (total < 10) {
total += 1;
}
}
null 값 초기화 시 유용한 팁
void main(){
/* ??= */
double? number = 4.0;
number = null;
number ??= 3.0; // number 가 null이면 오른쪽 값으로 변경
print(number); // 3
}