void main() {
var name = '찌니월드';
print(name); // 찌니월드
// 변수값 변경 가능
name = '코코몽';
print(name); // 코코몽
// 변수명 중복은 불가능
// 그래서 다음 코드에서 주석을 제거하면 코드에서 에러 발생
// var name = '코코찌니';
}
void main() {
dynamic name = '찌니월드';
print(name); // 찌니월드
name = 1;
print(name); // 1
}
void main() {
final String name = '찌니월드';
name = '코코몽'; // 에러 발생. final로 선언한 변수는 선언 후 값을 변경할 수 없음
const String name2 = '코코몽';
name2 = '찌니월드'; // 에러 발생. const로 선언한 변수는 선언 후 값을 변경할 수 없음
}
final은 런타임, const는 빌드 타임 상수이다.
구체적인 차이점을 알아보기 위해서 DateTime.now() 함수를 이용해 알아보자.
void main() {
final DateTime now = DateTime.now();
print(now);
}
반면에 const를 사용하면 에러가 난다. const로 지정한 변수는 빌드 타임에 값을 알 수 있어야 하는데 DateTime.now() 함수는 런타임에 반환되는 값을 알 수 있기 때문이다.
void main() {
// 에러
const DateTime now = DateTime.now();
print(now);
}
📢 코드를 실행하지 않은 상태에서 값이 확정되면 const를, 실행될 때 확정되면 final을 사용해주자.
void main() {
// String - 문자열
String name = '찌니월드';
// int - 정수
int isInt = 10;
// double - 실수
double isDouble = 2.5;
// bool - 불리언 (true/false)
bool isTrue = true;
print(name); // 찌니월드
print(isInt); // 10
print(isDouble); // 2.5
print(isTrue); // true
}
void main() {
// 리스트에 넣을 타입을 <> 사이에 명시할 수 있다.
List<String> fruitList = ['사과', '바나나', '체리', '딸기'];
print(fruitList);
print(fruitList[0]); // 첫 원소 지정
print(fruitList[3]); // 마지막 원소 지정
print(fruitList.length); // 길이 반환
fruitList[3] = '포도';
print(fruitList); // [사과, 바나나, 체리, 포도]
}
void main() {
List<String> fruitList = ['사과', '바나나', '체리', '딸기'];
fruitList.add('망고'); // 리스트의 끝에 추가
print(fruitList); // [사과, 바나나, 체리, 딸기, 망고]
}
void main() {
List<String> fruitList = ['사과', '바나나', '체리', '딸기'];
final newList = fruitList.where(
(name) => name == '체리' || name == '딸기', // '체리' 또는 '딸기'만 유지
);
print(newList);
print(newList.toList()); // Iterable을 List로 다시 변환할 때 .toList() 사용
}
void main() {
List<String> fruitList = ['사과', '바나나', '체리', '딸기'];
final newfruitList = fruitList.map(
(name) => '과일 $name', // 리스트의 모든 값 앞에 '과일' 추가
);
print(newfruitList);
print(newfruitList.toList()); // Iterable을 List로 다시 변환하고 싶을 때 .toList() 사용
}
void main() {
List<String> fruitList = ['사과', '바나나', '체리', '딸기'];
final allFruits = fruitList.reduce((value, element) => value + ',' + element);
print(allFruits); // 사과,바나나,체리,딸기
}
순회가 처음 시작될 때 첫 번째 매개변수는 리스트의 첫 번째 값 즉, '사과'를 받게 되고, 두 번째 매개변수는 '바나나'를 받게 된다.
첫 번째 순회 이후로는 첫 번째 매개변수에 기존 순회에서 반환한 값이 첫 번째 매개변수에 입력되고 리스트에서의 다음 값이(체리) 두 번째 매개변수에 입력된다.
void main() {
List<String> fruitList = ['사과', '바나나', '체리', '딸기'];
final allFruits = fruitList.fold<int>(0, (value, element) => value + element.length);
print(allFruits); // 9
}
void main() {
Map<String, String> dictionary = {
'Harry Potter': '해리 포터', // 키 : 값
'Ron Weasley': '론 위즐리',
'Hermione Granger': '헤르미온느 그레인저',
};
print(dictionary['Harry Potter']); // 해리 포터
print(dictionary['Hermione Granger']); // 헤르미온느 그레인저
}
void main() {
Map<String, String> dictionary = {
'Harry Potter': '해리 포터', // 키 : 값
'Ron Weasley': '론 위즐리',
'Hermione Granger': '헤르미온느 그레인저',
};
print(dictionary.keys); // (Harry Potter, Ron Weasley, Hermione Granger)
print(dictionary.values); // (해리 포터, 론 위즐리, 헤르미온느 그레인저)
}
void main() {
Set<String> fruit = {'포도', '사과', '딸기', '딸기'}; // 딸기 중복
print(fruit); // {포도, 사과, 딸기}
print(fruit.contains('포도')); // 값이 있는지 확인하기
print(fruit.toList()); // 리스트로 변환하기
List<String> fruit2 = ['포도', '사과', '사과'];
print(Set.from(fruit2)); // List 타입을 Set 타입으로 변환
}
enum Status {
approved,
pending,
rejected,
}
void main() {
Status status = Status.approved;
print(status); // Status.approved
}
다트 언어에서는 변수 타입이 null값을 가지는지 여부를 직접 지정해줘야 한다.
void main() {
// 타입 뒤에 ?를 명시해서 null값을 가질 수 있다.
double? number1 = 1;
// 타입 뒤에 ?를 명시하지 않아 에러가 난다.
double number2 = null;
}
null을 가질 수 있는 변수에 새로운 값을 추가할 때 ??를 사용하면 기존에 null인 때만 값이 저장되도록 할 수 있다.
void main() {
double? number; // 자동으로 null값 지정
print(number);
number ??= 3; // ??를 사용하면 기존 값이 null일 때만 저장된다.
print(number);
number ??= 4; // null이 아니므로 3이 유지된다.
print(number);
}
void main() {
int number1 = 1;
print(number1 is int); // true
print(number1 is String); // false
print(number1 is! int); // false. !는 반대를 의미한다.(int 타입이 아닌 경우 true)
print(number1 is! String); // true
}
void main() {
int number = 2;
if (number % 3 == 0) {
print('3의 배수입니다.');
} else if (number % 3 == 1) {
print('나머지가 1입니다.');
} else {
print('맞는 조건이 없습니다.');
}
}
enum Status {
approved,
pending,
rejected,
}
void main() {
Status status = Status.approved;
switch (status) {
case Status.approved:
print('승인 상태입니다.');
break;
case Status.pending:
print('대기 상태입니다.');
break;
case Status.rejected:
print('거절 상태입니다.');
break;
default:
print('알 수 없는 상태입니다.');
}
}
void main() {
// 값 선언; 조건 설정; loop마다 실행할 기능
for (int i = 0; i < 3; i++) {
print(i);
}
}
void main() {
List<int> numberList = [3, 6, 9];
for (int number in numberList) {
print(number);
}
}
while문은 조건을 기반으로 반복문을 실행한다. 조건이 true이면 계속 실행하고 false이면 멈추게 된다.
void main() {
int total = 0;
while(total < 10) { // total 값이 10보다 작으면 계속 실행
total += 1;
}
print(total);
}
void main() {
int total = 0;
do {
total += 1;
} while (total < 10);
print(total);
}
- 함수를 사용하면 한 번만 작성하고 여러 곳에서 재활용 가능
- 반환할 값이 없을 때는 void 키워드를 사용
- 다트 함수에서 매개변수를 지정하는 방법
- 순서가 고정된 매개변수(포지셔널 파라미터)
- 이름이 있는 매개변수(네임드 파라미터)
int addTwoNumbers(int a, [int b = 2]) {
return a + b;
}
void main() {
print(addTwoNumbers(1)); // 3
}
int addTwoNumbers({
required int a,
int b = 2,
}) {
return a + b;
}
void main() {
print(addTwoNumbers(a: 1)); // 3
}
(매개변수) {
함수 바디
}
}
(매개변수) => 단 하나의 스테이트먼트
typedef Operation = void Function(int x, int y);
void add(int x, int y) {
print('결과값: ${x + y}');
}
void subtract(int x, int y) {
print('결과값: ${x - y}');
}
void main() {
// typedef는 일반적인 변수의 type처럼 사용 가능
Operation oper = add;
oper(1, 2); // 결과값: 3
// subtract() 함수도 Operation에 해당되는
// 시그니처이므로 oper 변수에 저장 가능
oper = subtract;
oper(1, 2); // 결과값: -1
}
특정 코드의 실행을 시도(try)해보고 문제가 있다면 에러를 잡으라(catch)는 뜻이다.
void main() {
try{
// 에러가 없을 때 실행할 로직
final String name = '찌니월드';
print(name); // 찌니월드
}catch(e){ // catch는 첫 번째 매개변수에 에러 정보를 전달해준다.
// 에러가 있을 때 실행할 로직
print(e);
}
}
throw 키워드를 사용해 에러를 발생시킬 수도 있다.
void main() {
try{
final String name = '움파룸파';
// throw 키워드로 고의적으로 에러를 발생시켜보자
throw Exception('이름이 잘못됐습니다!');
print(name);
}catch(e){
// try에서 에러가 발생했으니 catch 로직이 실행된다.
print(e);
}
}
throw 키워드를 사용해서 에러를 발생시키니 try에 있는 로직 실행이 중지되고 catch 로직이 실행됐다. 그래서 name 변수 값은 출력되지 않고 발생한 에러 메시지가 출력되었다.
이 글은 골든래빗 《코드팩토리의 플러터 프로그래밍》의 스터디 내용 입니다.