출시·고도화 중
Dart 안내서 · 2/6
Dart의 문법은 C, Java, JavaScript에 익숙한 사람이라면 금방 읽을 수 있습니다. 중괄호로 블록을 나누고, 문장은 세미콜론으로 끝냅니다. 이 장에서는 변수 선언, 함수, 문자열 보간, 제어 흐름, 컬렉션 리터럴을 차례로 살펴봅니다.
Dart는 정적 타입 언어지만 타입 추론이 강력해서 대부분 타입을 생략할 수 있습니다. 변수를 선언하는 방법은 세 가지입니다.
| 키워드 | 다시 대입 | 값이 정해지는 때 |
|---|---|---|
var | 됩니다 | 실행 중 |
final | 안 됩니다(한 번만 대입) | 실행 중 |
const | 안 됩니다 | 컴파일할 때 |
void main() {
var count = 0; // int 로 추론
count = count + 1; // 다시 대입할 수 있습니다
final now = DateTime.now(); // 실행 중에 한 번 정해짐
const maxUsers = 100; // 컴파일 시점 상수
const colors = ['red', 'green']; // 리스트 전체가 바뀌지 않는 상수
String title = 'Dart'; // 타입을 직접 적어도 됩니다
late String description; // 나중에 반드시 초기화하겠다는 약속
}권장 스타일은 다시 대입하지 않는 지역 변수에 final을 쓰고, 컴파일 시점에 정해지는 값에는 const를 쓰는 것입니다. late는 선언과 초기화를 나눌 때 쓰며, 초기화하기 전에 읽으면 실행 중 오류가 납니다.
문자열은 작은따옴표나 큰따옴표로 감쌉니다. 둘은 의미가 같고, 공식 스타일은 작은따옴표를 권장합니다. $변수 또는 ${식}으로 값을 문자열 안에 넣을 수 있습니다.
void main() {
final name = '하나';
final items = 3;
print('안녕하세요, $name 님');
print('장바구니에 ${items * 2}개가 있습니다');
print('이름 길이: ${name.length}');
final multiLine = '''
여러 줄 문자열은
따옴표 세 개로 씁니다.
''';
final raw = r'C:\temp\$notInterpolated'; // r 접두사는 원시 문자열
}함수는 반환 타입, 이름, 매개변수 목록으로 선언합니다. 본문이 식 하나뿐이면 화살표(=>) 문법으로 줄일 수 있습니다.
int add(int a, int b) {
return a + b;
}
int square(int x) => x * x;
// 이름 있는 매개변수: 중괄호, required 또는 기본값
String greet({required String name, String greeting = '안녕하세요'}) {
return '$greeting, $name!';
}
// 선택적 위치 매개변수: 대괄호, null 이 될 수 있는 타입 또는 기본값
String label(String text, [String? suffix]) {
return suffix == null ? text : '$text ($suffix)';
}
void main() {
print(add(2, 3)); // 5
print(square(4)); // 16
print(greet(name: '민수')); // 안녕하세요, 민수!
print(greet(greeting: '반가워요', name: '지우'));
print(label('파일')); // 파일
print(label('파일', '읽기 전용')); // 파일 (읽기 전용)
}이름 있는 매개변수는 호출할 때 이름을 붙이므로 순서를 바꿔도 되고, 읽기도 쉽습니다. Flutter 위젯의 생성자가 대부분 이 방식을 씁니다. 함수는 일급 값이라 변수에 담거나 다른 함수에 넘길 수 있고, (x) => x * 2 같은 익명 함수도 자주 씁니다.
if/else, for, while, do-while은 다른 C 계열 언어와 같습니다. 조건식은 반드시 bool이어야 하며, 0이나 빈 문자열을 거짓으로 취급하지 않습니다.
void main() {
final scores = [72, 95, 88];
for (var i = 0; i < scores.length; i++) {
print('$i번째: ${scores[i]}');
}
for (final score in scores) {
if (score >= 90) {
print('$score: 우수');
} else if (score >= 80) {
print('$score: 양호');
} else {
print('$score: 보통');
}
}
var n = 3;
while (n > 0) {
print(n--);
}
// switch 식: 값을 돌려주는 switch
final day = 6;
final kind = switch (day) {
6 || 7 => '주말',
>= 1 && <= 5 => '평일',
_ => '알 수 없음',
};
print(kind);
}Dart 3부터 switch 문은 내용이 있는 case가 다음 case로 흘러가지 않으므로 break를 쓰지 않아도 됩니다. switch 식은 각 갈래가 값을 돌려주고, 위 예처럼 ||, 비교, _(나머지 모두) 같은 패턴을 쓸 수 있습니다. 패턴은 다음 장에서 자세히 다룹니다.
자주 쓰는 연산자 몇 가지를 알아 두면 코드가 훨씬 짧아집니다.
a ?? b: a가 null이면 b를 씁니다.a ??= b: a가 null일 때만 b를 대입합니다.obj?.method(): obj가 null이면 호출하지 않고 null을 돌려줍니다.obj..a = 1..b(): 캐스케이드. 같은 객체에 여러 작업을 이어서 합니다.void main() {
String? nickname;
print(nickname ?? '손님'); // 손님
nickname ??= '익명';
print(nickname.length); // 2 (여기서는 null 이 아님이 확인됨)
String? missing;
print(missing?.length); // null
final buffer = StringBuffer()
..write('Dart')
..write(' 문법')
..write(' 정리');
print(buffer.toString());
}리스트는 [], 집합은 {}에 값만, 맵은 {}에 키: 값을 씁니다. 컬렉션 안에서 if, for, 펼치기(...)를 쓸 수 있어 조건에 따라 항목을 넣거나 다른 컬렉션을 합치기 쉽습니다.
final isAdmin = true;
final base = ['홈', '검색'];
final menu = [
...base,
if (isAdmin) '관리',
for (var i = 1; i <= 2; i++) '메뉴 $i',
];
print(menu); // [홈, 검색, 관리, 메뉴 1, 메뉴 2]
final tags = {'dart', 'flutter', 'dart'}; // Set: 중복 제거
final ages = {'민수': 31, '지우': 27}; // Map<String, int>
final empty = <String>{}; // 빈 Set 은 타입을 적어야 합니다
print(tags.length); // 2
print(ages['지우']); // 27빈 {}는 맵으로 해석되므로, 빈 집합이 필요하면 <String>{}처럼 타입 인자를 붙입니다.
Dart는 var, final, const로 변수의 성격을 구분하고, $와 ${}로 문자열 보간을 합니다. 함수는 이름 있는 매개변수, 선택적 위치 매개변수, 화살표 문법을 지원하고, 제어 흐름은 C 계열과 비슷하지만 switch 식과 패턴이 더해졌습니다. ??, ?., 캐스케이드, 컬렉션 if와 for를 익혀 두면 짧고 읽기 쉬운 코드를 쓸 수 있습니다.
댓글 0개
로그인 · 로그인하면 댓글을 남길 수 있습니다.
첫 댓글을 남겨 보세요.