πŸ“

Dart Basic Syntax

Variables, strings, operators, Null Safety basics

Dart programs start from main(). The core syntax includes 6 variable declaration styles (var, final, const, late, dynamic), string interpolation, Null Safety operators (?., ??, !, ??=), and the cascade (..) operator. Mastering these basics is essential for reading and writing Flutter code naturally.

Dart ν”„λ‘œκ·Έλž¨μ˜ ꡬ쑰

λͺ¨λ“  Dart ν”„λ‘œκ·Έλž¨μ€ main() ν•¨μˆ˜μ—μ„œ μ‹œμž‘ν•©λ‹ˆλ‹€. voidλŠ” λ°˜ν™˜κ°’μ΄ μ—†μŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

void main() { print('μ•ˆλ…•ν•˜μ„Έμš”, Dart!'); } // μ»€λ§¨λ“œλΌμΈ 인자λ₯Ό λ°›λŠ” 경우 void main(List<String> arguments) { print('ν”„λ‘œκ·Έλž¨ 인자: $arguments'); }

주석 (Comments)

// ν•œ 쀄 주석 /* μ—¬λŸ¬ 쀄 주석 μ—¬λŸ¬ 쀄에 걸쳐 μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€. */ /// λ¬Έμ„œν™” 주석 /// dartdoc 도ꡬ가 API λ¬Έμ„œλ₯Ό 생성할 λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€. /// 클래슀, ν•¨μˆ˜, λ³€μˆ˜ λ“±μ˜ μ„€λͺ…을 μž‘μ„±ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€.

κΈ°λ³Έ 데이터 νƒ€μž…

// 숫자 νƒ€μž… int integerValue = 42; // μ •μˆ˜ double doubleValue = 3.14; // μ‹€μˆ˜ num numValue = 10; // intλ‚˜ double의 μƒμœ„ νƒ€μž… // λ¬Έμžμ—΄ νƒ€μž… String greeting = 'μ•ˆλ…•ν•˜μ„Έμš”'; // λΆˆλ¦¬μ–Έ νƒ€μž… bool isTrue = true; bool isFalse = false; // 리슀트 (λ°°μ—΄) List<int> numbers = [1, 2, 3, 4, 5]; // λ§΅ (key-value 쌍) Map<String, dynamic> person = { 'name': '홍길동', 'age': 30, 'isStudent': false }; // μ§‘ν•© (쀑볡 μ—†λŠ” μ»¬λ ‰μ…˜) Set<String> uniqueNames = {'홍길동', 'κΉ€μ² μˆ˜', '이영희'};

λ³€μˆ˜ μ„ μ–Έ 방식 비ꡐ

ν‚€μ›Œλ“œνƒ€μž… μΆ”λ‘ μž¬ν• λ‹Ήμ΄ˆκΈ°ν™” μ‹œμ 
varμžλ™κ°€λŠ₯μ„ μ–Έ μ‹œ
finalμžλ™λΆˆκ°€λŸ°νƒ€μž„
constμžλ™λΆˆκ°€μ»΄νŒŒμΌ νƒ€μž„
lateμˆ˜λ™κ°€λŠ₯λ‚˜μ€‘μ—
dynamicμ—†μŒκ°€λŠ₯ (νƒ€μž… 변경도 κ°€λŠ₯)μ„ μ–Έ μ‹œ

var β€” νƒ€μž… μΆ”λ‘  λ³€μˆ˜

μ΄ˆκΈ°κ°’μ—μ„œ νƒ€μž…μ΄ μžλ™ μΆ”λ‘ λ˜λ©°, 이후 λ‹€λ₯Έ νƒ€μž…μ˜ 값은 ν• λ‹Ήν•  수 μ—†μŠ΅λ‹ˆλ‹€.

var name = '홍길동'; // String으둜 μΆ”λ‘  var age = 30; // int둜 μΆ”λ‘  var height = 175.5; // double으둜 μΆ”λ‘  name = 'κΉ€μ² μˆ˜'; // κ°€λŠ₯ (String β†’ String) // name = 42; // 였λ₯˜ (String β†’ int)

λͺ…μ‹œμ  νƒ€μž… μ„ μ–Έ

String name = '홍길동'; int age = 30; double height = 175.5;

finalκ³Ό const

// final: λŸ°νƒ€μž„μ— 값이 κ²°μ •λ˜λŠ” μƒμˆ˜ final String name = '홍길동'; final currentTime = DateTime.now(); // νƒ€μž… μΆ”λ‘  κ°€λŠ₯ // const: 컴파일 νƒ€μž„μ— 값이 κ²°μ •λ˜λŠ” μƒμˆ˜ const int maxUsers = 100; const double pi = 3.14159; // μž¬ν• λ‹Ή λΆˆκ°€ // name = 'κΉ€μ² μˆ˜'; // 였λ₯˜: final λ³€μˆ˜λŠ” μž¬ν• λ‹Ή λΆˆκ°€ // maxUsers = 200; // 였λ₯˜: const λ³€μˆ˜λŠ” μž¬ν• λ‹Ή λΆˆκ°€

final vs const 핡심 차이

final은 λŸ°νƒ€μž„μ— 값이 결정될 수 μžˆμ§€λ§Œ, constλŠ” 컴파일 μ‹œμ μ— 값을 μ•Œ 수 μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.

final now = DateTime.now(); // κ°€λŠ₯ (λŸ°νƒ€μž„ κ°’) // const today = DateTime.now(); // 였λ₯˜: 컴파일 μ‹œμ μ— 값을 μ•Œ 수 μ—†μŒ

late β€” μ§€μ—° μ΄ˆκΈ°ν™”

μ„ μ–Έ μ‹œ μ΄ˆκΈ°ν™”ν•˜μ§€ μ•Šκ³  λ‚˜μ€‘μ— 값을 ν• λ‹Ήν•©λ‹ˆλ‹€. μ΄ˆκΈ°ν™” 전에 μ ‘κ·Όν•˜λ©΄ λŸ°νƒ€μž„ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

late String name; void initName() { name = '홍길동'; // λ‚˜μ€‘μ— κ°’ ν• λ‹Ή } void main() { initName(); print(name); // '홍길동' late String address; // print(address); // 였λ₯˜: μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ€ late λ³€μˆ˜μ— μ ‘κ·Ό }

dynamic β€” 동적 νƒ€μž…

μ–΄λ–€ νƒ€μž…μ˜ 값이든 ν• λ‹Ή κ°€λŠ₯ν•˜λ©°, 컴파일 νƒ€μž„ νƒ€μž… 검사λ₯Ό μš°νšŒν•©λ‹ˆλ‹€.

dynamic value = 'λ¬Έμžμ—΄'; print(value); // 'λ¬Έμžμ—΄' value = 42; print(value); // 42 value = true; print(value); // true

λ¬Έμžμ—΄ (String)

μž‘μ€λ”°μ˜΄ν‘œμ™€ ν°λ”°μ˜΄ν‘œ λͺ¨λ‘ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

String single = 'μž‘μ€λ”°μ˜΄ν‘œ λ¬Έμžμ—΄'; String double_ = "ν°λ”°μ˜΄ν‘œ λ¬Έμžμ—΄";

λ¬Έμžμ—΄ 보간 (Interpolation)

String name = '홍길동'; int age = 30; // $λ³€μˆ˜λͺ… ν˜•νƒœ String message = '제 이름은 $name이고, λ‚˜μ΄λŠ” $ageμ‚΄μž…λ‹ˆλ‹€.'; // ${ν‘œν˜„μ‹} ν˜•νƒœ String ageNextYear = 'λ‚΄λ…„μ—λŠ” ${age + 1}살이 λ©λ‹ˆλ‹€.';

μ—¬λŸ¬ 쀄 λ¬Έμžμ—΄ & μ›μ‹œ λ¬Έμžμ—΄

// μ—¬λŸ¬ 쀄 λ¬Έμžμ—΄ β€” 삼쀑 λ”°μ˜΄ν‘œ String multiLine = ''' 이것은 μ—¬λŸ¬ 쀄에 걸친 λ¬Έμžμ—΄μž…λ‹ˆλ‹€. '''; // μ›μ‹œ λ¬Έμžμ—΄ β€” r 접두사 (μ΄μŠ€μΌ€μ΄ν”„ 처리 μ•ˆ 함) String escaped = 'C:\Program Files\Dart'; // μ΄μŠ€μΌ€μ΄ν”„ μ‚¬μš© String raw = r'C:\Program Files\Dart'; // μ›μ‹œ λ¬Έμžμ—΄

μ‚°μˆ  μ—°μ‚°μž

int a = 10; int b = 3; print(a + b); // 13 (λ§μ…ˆ) print(a - b); // 7 (λΊ„μ…ˆ) print(a * b); // 30 (κ³±μ…ˆ) print(a / b); // 3.333... (λ‚˜λˆ—μ…ˆ, κ²°κ³ΌλŠ” double) print(a ~/ b); // 3 (μ •μˆ˜ λ‚˜λˆ—μ…ˆ, κ²°κ³ΌλŠ” int) print(a % b); // 1 (λ‚˜λ¨Έμ§€)

/λŠ” 항상 double을 λ°˜ν™˜ν•©λ‹ˆλ‹€. μ •μˆ˜ κ²°κ³Όκ°€ ν•„μš”ν•˜λ©΄ ~/λ₯Ό μ‚¬μš©ν•˜μ„Έμš”.

증감 & ν• λ‹Ή μ—°μ‚°μž

int a = 10; a++; // ν›„μœ„ 증가 β†’ 11 ++a; // μ „μœ„ 증가 β†’ 12 a--; // ν›„μœ„ κ°μ†Œ β†’ 11 --a; // μ „μœ„ κ°μ†Œ β†’ 10 // ν• λ‹Ή μ—°μ‚°μž a += 5; // a = a + 5 β†’ 15 a -= 3; // a = a - 3 β†’ 12 a *= 2; // a = a * 2 β†’ 24 a ~/= 5; // a = a ~/ 5 β†’ 4

비ꡐ & 논리 μ—°μ‚°μž

// 비ꡐ μ—°μ‚°μž int a = 10, b = 5; print(a == b); // false (κ°™μŒ) print(a != b); // true (닀름) print(a > b); // true (초과) print(a < b); // false (미만) print(a >= b); // true (이상) print(a <= b); // false (μ΄ν•˜) // 논리 μ—°μ‚°μž bool c1 = true, c2 = false; print(c1 && c2); // false (AND) print(c1 || c2); // true (OR) print(!c1); // false (NOT)

νƒ€μž… ν…ŒμŠ€νŠΈ μ—°μ‚°μž

var value = 'λ¬Έμžμ—΄'; print(value is String); // true (String νƒ€μž…μΈμ§€ 확인) print(value is! int); // true (int νƒ€μž…μ΄ μ•„λ‹Œμ§€ 확인) // as μ—°μ‚°μž β€” λͺ…μ‹œμ  νƒ€μž… λ³€ν™˜ dynamic someValue = 'Dart'; String text = someValue as String;

쑰건 μ—°μ‚°μž

// μ‚Όν•­ μ—°μ‚°μž: 쑰건 ? κ°’1 : κ°’2 int a = 10, b = 5; int max = a > b ? a : b; print(max); // 10 // ?? μ—°μ‚°μž: μ™Όμͺ½μ΄ null이면 였λ₯Έμͺ½ λ°˜ν™˜ String? name; String displayName = name ?? '이름 μ—†μŒ'; print(displayName); // '이름 μ—†μŒ'

μΊμŠ€μΌ€μ΄λ“œ(..) μ—°μ‚°μž

동일 객체에 μ—°μ†μœΌλ‘œ λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜κ±°λ‚˜ 속성을 μ„€μ •ν•  λ•Œ μ‚¬μš©ν•©λ‹ˆλ‹€.

class Person { String name = ''; int age = 0; void introduce() { print('λ‚΄ 이름은 $name이고, λ‚˜μ΄λŠ” $ageμ‚΄μž…λ‹ˆλ‹€.'); } } void main() { var person = Person() ..name = '홍길동' ..age = 30 ..introduce(); // μœ„ μ½”λ“œλŠ” λ‹€μŒκ³Ό λ™μΌν•©λ‹ˆλ‹€: // var person = Person(); // person.name = '홍길동'; // person.age = 30; // person.introduce(); }

Null Safety

Dart 2.12λΆ€ν„° λ„μž…λœ Null SafetyλŠ” 컴파일 νƒ€μž„μ— null μ°Έμ‘° 였λ₯˜λ₯Ό λ°©μ§€ν•©λ‹ˆλ‹€.

// non-nullable νƒ€μž… (null ν• λ‹Ή λΆˆκ°€) String name = '홍길동'; // name = null; // 컴파일 였λ₯˜ // nullable νƒ€μž… (? μΆ”κ°€ β†’ null ν—ˆμš©) String? nullableName = '홍길동'; nullableName = null; // ν—ˆμš©λ¨

Null Safety μ—°μ‚°μž 비ꡐ

μ—°μ‚°μžμ΄λ¦„λ™μž‘μ˜ˆμ‹œ
?.쑰건뢀 접근객체가 null이면 전체 ν‘œν˜„μ‹μ΄ nullname?.length
??null 병합왼μͺ½μ΄ null이면 였λ₯Έμͺ½ λ°˜ν™˜name ?? 'κΈ°λ³Έκ°’'
??=null ν• λ‹Ήλ³€μˆ˜κ°€ null이면 값을 ν• λ‹Ήname ??= 'κΈ°λ³Έκ°’'
!non-null 단언null이 μ•„λ‹˜μ„ 단언 (μœ„ν—˜)name!

Null Safety μ—°μ‚°μž μ½”λ“œ 예제

String? name = getNullableName(); // null 검사 ν›„ μ‚¬μš© if (name != null) { print('μ΄λ¦„μ˜ 길이: ${name.length}'); } // ?. β€” 쑰건뢀 μ ‘κ·Ό (null이면 null λ°˜ν™˜) print('μ΄λ¦„μ˜ 길이: ${name?.length}'); // ?? β€” null 병합 (null이면 κΈ°λ³Έκ°’) print('이름: ${name ?? '이름 μ—†μŒ'}'); // ??= β€” null이면 값을 ν• λ‹Ή name ??= '이름 μ—†μŒ';

non-null 단언 μ—°μ‚°μž (!)

주의: ! μ—°μ‚°μžλŠ” μ‹€μ œ null인 경우 λŸ°νƒ€μž„ 였λ₯˜λ₯Ό λ°œμƒμ‹œν‚΅λ‹ˆλ‹€. κ°€λŠ₯ν•˜λ©΄ ??λ‚˜ ?.을 μš°μ„  μ‚¬μš©ν•˜μ„Έμš”.

String? name = '홍길동'; // null이 μ•„λ‹ˆλΌκ³  ν™•μ‹ ν•  λ•Œ μ‚¬μš© String nonNullName = name!; // μ‹€μ œλ‘œ null이면 λŸ°νƒ€μž„ 였λ₯˜ λ°œμƒ name = null; // String error = name!; // λŸ°νƒ€μž„ 였λ₯˜: null μ°Έμ‘°

Implementation Steps

1

var vs final vs const β€” var is reassignable, final is runtime constant, const is compile-time constant

2

late keyword β€” declare without initialization, essential for lazy init of non-nullable variables

3

String interpolation β€” insert values with "$var" or "${expr}", preferred over + concatenation

4

Null Safety operators β€” ?. (null returns null), ?? (default if null), ! (non-null assert, risky), ??= (assign if null)

5

Cascade (..) operator β€” chain calls on same object, useful like builder pattern

Pros

  • Clear immutability expression with final/const
  • Null Safety prevents NullPointerException at compile time

Cons

  • final vs const distinction can confuse beginners

Use Cases

Understanding variables and Null Safety before writing Flutter code