Post

[Capstone-Start] Dart ํ•™์Šต โ€” Records, Patterns, Switch Expression

[Capstone-Start] Dart ํ•™์Šต โ€” Records, Patterns, Switch Expression

๐Ÿ“… ์ผ์‹œ: 2026. 05. 26

๐Ÿ’ฌ ๋‚ด์šฉ: Dart 3์˜ ์ƒˆ ๊ธฐ๋Šฅ โ€” Records, Pattern Matching, Switch Expression์ด ์‹ค์ œ ์ฝ”๋“œ์— ์–ด๋–ป๊ฒŒ ๋“ค์–ด๊ฐ”๋Š”์ง€ ์ •๋ฆฌ


์บก์Šคํ†ค ์‹œ์—ฐ ํ™˜๊ฒฝ์ด ์–ด์ œ(5/25) ์•ˆ์ •ํ™”๋œ ํ›„, ์˜ค๋Š˜์€ ๊ทธ๋™์•ˆ ์ง  ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ ํ›‘์œผ๋ฉฐ ์ •๋ฆฌํ•˜๋Š” ์‹œ๊ฐ„์„ ๊ฐ€์กŒ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฉด์„œ ๊นจ๋‹ฌ์€ ๊ฒŒ, Dart 3์—์„œ ์ƒˆ๋กœ ๋“ค์–ด์˜จ records / patterns / switch expression์ด ์ฝ”๋“œ ๊ณณ๊ณณ์— ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋ฐ•ํ˜€ ์žˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. Stage 8์—์„œ (_, _) wildcard๋ฅผ ์“ฐ๊ฑฐ๋‚˜, Stage 2์—์„œ Result<T> switch matching์„ ๊น”๊ฑฐ๋‚˜, fl_chart ๋ฐ์ดํ„ฐ์— (double x, double y) records๋ฅผ ์“ฐ๋Š” ๋“ฑ์˜ ํ”์ ์ด ๋‚จ์•„ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

์ฒ˜์Œ์— ์ด ๊ธฐ๋Šฅ๋“ค์„ ์“ธ ๋•Œ๋Š” โ€œKotlin ๋น„์Šทํ•œ ๊ฒƒโ€์ด๋ผ๋Š” ์ง๊ด€์œผ๋กœ ๋ฐ•์•˜๋Š”๋ฐ, ์˜ค๋Š˜ ๋‹ค์‹œ ์ •๋ฆฌํ•˜๋ฉด์„œ ์ •์‹ ํ•™์Šต ๋…ธํŠธ๋กœ ๋‚จ๊ฒจ ๋‘ก๋‹ˆ๋‹ค. ๊ฒ€์ƒ‰ํ•ด์„œ ๋“ค์–ด์˜ค์‹  ๋ถ„๊ป˜ ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋„๋ก Dart 2 ์‹œ์ ˆ ์ฝ”๋“œ์™€ Dart 3 ์ฝ”๋“œ์˜ before/after๋ฅผ ๊ฐ™์ด ๋ณด์—ฌ๋“œ๋ฆฌ๋Š” ํ˜•ํƒœ๋กœ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

1. Records โ€” ์ฆ‰์„์—์„œ ๋งŒ๋“œ๋Š” tuple

Record๋Š” ์—ฌ๋Ÿฌ ๊ฐ’์„ ํ•˜๋‚˜์˜ immutable ๋ฌถ์Œ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒฝ๋Ÿ‰ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. Python์˜ tuple, Kotlin์˜ Pair/Triple, TypeScript์˜ anonymous object์™€ ๋น„์Šทํ•œ ๊ฐœ๋…์ž…๋‹ˆ๋‹ค.

Positional Records

1
2
3
4
(int, String) pair = (1, 'apple');

print(pair.$1); // 1
print(pair.$2); // apple

ํ•„๋“œ๋ช…์ด ์—†๋Š” record๋Š” $1, $2 ์‹์œผ๋กœ ์œ„์น˜ ์ธ๋ฑ์Šค๋กœ ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•  ๋•Œ ๋ณ„๋„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์ฆ‰์„์—์„œ ์“ธ ์ˆ˜ ์žˆ์–ด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

1
2
3
(int, int) divmod(int a, int b) => (a ~/ b, a % b);

final (q, r) = divmod(17, 5); // q = 3, r = 2

์ขŒ๋ณ€์— (q, r) ํŒจํ„ด์„ ์“ฐ๋ฉด ํ•œ ์ค„์— destructuring์ด ๋ฉ๋‹ˆ๋‹ค.

Named Records โ€” ({ ... })

1
2
3
4
({int x, int y}) point = (x: 10, y: 20);

print(point.x); // 10
print(point.y); // 20

ํ•„๋“œ๋ช…์ด ์žˆ๋Š” record๋Š” ์  ํ‘œ๊ธฐ๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ณ , ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ๋” ๋ช…ํ™•ํ•ด์ง‘๋‹ˆ๋‹ค. ์บก์Šคํ†ค์˜ fl_chart ๋ž˜ํผ์—์„œ๋Š” ์ขŒํ‘œ๋ฅผ ({double x, double y}) ํ˜•ํƒœ์˜ record๋กœ ๋ฐ›๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
class AppLineChart extends StatelessWidget {
  const AppLineChart({super.key, required this.points, ...});
  final List<({double x, double y})> points;
}

// ํ˜ธ์ถœ
AppLineChart(points: [
  (x: 0, y: 70),
  (x: 1, y: 71),
  (x: 2, y: 72.5),
]);

์ฐจํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‹œ๊ทธ๋‹ˆ์ฒ˜์— ๋„๋ฉ”์ธ ํƒ€์ž…์„ ๋…ธ์ถœํ•˜์ง€ ์•Š์œผ๋ฉด์„œ๋„, point.x/point.y ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•œ ๊ฐ€๋…์„ฑ์„ ์–ป์—ˆ์Šต๋‹ˆ๋‹ค. ์ž„์‹œ ๋ฐ์ดํ„ฐ ๋ฌถ์Œ์—๋Š” record๊ฐ€ ๊ฑฐ์˜ ํ•ญ์ƒ ๋‹ต์ž…๋‹ˆ๋‹ค.

Records๋ฅผ ํด๋ž˜์Šค ๋Œ€์‹  ์“ฐ๋Š” ๊ฐ€์ด๋“œ

๋‹ค๋งŒ record๊ฐ€ ๋งŒ๋Šฅ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๋‹ค์Œ ๊ธฐ์ค€์œผ๋กœ record vs class๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค.

  • ์ด๋ฆ„์ด ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€๋ฉด class โ€” User / Meal์ฒ˜๋Ÿผ ๋„๋ฉ”์ธ ์˜๋ฏธ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด๋Š” ํด๋ž˜์Šค.
  • ํ•„๋“œ๊ฐ€ 3๊ฐœ ์ด์ƒ์ด๊ณ  ์žฌ์‚ฌ์šฉ๋œ๋‹ค๋ฉด class โ€” record๋Š” ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ๊ธธ์–ด์ง€๋ฉด ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์ง‘๋‹ˆ๋‹ค.
  • ๋ฉ”์„œ๋“œ๋ฅผ ๋ถ™์ด๊ณ  ์‹ถ์œผ๋ฉด class โ€” record๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • ๋กœ์ปฌยท์ž„์‹œยท๋ฐ˜ํ™˜๊ฐ’ ๋ฌถ์Œ์ด๋ฉด record โ€” ์งง๊ฒŒ ์‚ด์•„ ์žˆ์„ ๋ฐ์ดํ„ฐ์— ์ ํ•ฉ.

2. Patterns โ€” destructuring + ์กฐ๊ฑด ๋งค์นญ

Dart 3์˜ ํŒจํ„ด์€ ๋‘ ๊ฐ€์ง€ ์—ญํ• ์„ ๋™์‹œ์— ํ•ฉ๋‹ˆ๋‹ค.

  1. Destructuring โ€” ๋ณตํ•ฉ ๊ตฌ์กฐ์—์„œ ๊ฐ’์„ ๊บผ๋‚ด๊ธฐ
  2. Matching โ€” ์–ด๋–ค ํ˜•ํƒœ์ธ์ง€ ๊ฒ€์‚ฌ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 1. Variable pattern โ€” ๊ทธ๋ƒฅ ๋ณ€์ˆ˜์— ๋‹ด๊ธฐ
final user = User(id: 1, name: '๋ฏผ์ˆ˜');
final User(:id, :name) = user;  // id = 1, name = '๋ฏผ์ˆ˜'

// 2. List pattern โ€” ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ์™€ ๋™์‹œ์— ๋ถ„ํ•ด
final list = [1, 2, 3];
if (list case [final first, _, final last]) {
  print('$first, $last'); // 1, 3
}

// 3. Map pattern
final json = {'type': 'circle', 'r': 5};
if (json case {'type': 'circle', 'r': final r}) {
  print(r); // 5
}

: ๋‹จ์ถ• (shorthand)

Object(:fieldName)์€ Object(fieldName: fieldName)์˜ ๋‹จ์ถ• ํ‘œ๊ธฐ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ ์ด๋ฆ„์˜ ๋ณ€์ˆ˜์— ๋ฐ”์ธ๋”ฉํ•  ๋•Œ ํ•œ ๊ธ€์ž๋ผ๋„ ์ค„์ด๋ ค๋Š” syntactic sugar์ž…๋‹ˆ๋‹ค.

1
2
3
4
5
// ํ’€์–ด์“ด ํ˜•ํƒœ
final Circle(r: r) = circle;

// ๋‹จ์ถ•ํ˜•
final Circle(:r) = circle;

Wildcard _ ํŒจํ„ด โ€” Stage 8์—์„œ ์‹ค์ œ ์‚ฌ์šฉ

์ด ๋ถ€๋ถ„์ด ์บก์Šคํ†ค ์ฝ”๋“œ์— ๊ฐ€์žฅ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋“ฑ์žฅํ•ฉ๋‹ˆ๋‹ค. separatorBuilder ๊ฐ™์€ ์ฝœ๋ฐฑ์€ ์ธ์ž ๋‘ ๊ฐœ๋ฅผ ๋ฐ›์ง€๋งŒ ๋‘˜ ๋‹ค ์•ˆ ์“ฐ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ „(Dart 2)์—๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ์ผ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
// Dart 2 โ€” ๋ฏธ์‚ฌ์šฉ ์ธ์ž์— ์ด๋ฆ„์„ ๋ถ™์—ฌ์•ผ ํ–ˆ์Œ
ListView.separated(
  itemCount: items.length,
  separatorBuilder: (context, index) => const Divider(),
  itemBuilder: ...,
)

Dart 3์—์„œ๋Š” wildcard _๋กœ โ€œ์•ˆ ์“ด๋‹คโ€๋Š” ์˜๋„๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
// Dart 3 โ€” ๋ฏธ์‚ฌ์šฉ ์ธ์ž๋ฅผ wildcard๋กœ
ListView.separated(
  itemCount: items.length,
  separatorBuilder: (_, _) => const Divider(),
  itemBuilder: (_, i) => ListTile(title: Text(items[i].name)),
)

Stage 8์—์„œ lint๊ฐ€ ์žก์•„์„œ ์ผ๊ด„๋กœ ์ •๋ฆฌํ–ˆ๋˜ ํ”์ ์ด ์žˆ๋Š”๋ฐ, ๊ทธ๊ฒŒ ์ด ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

1
2
style: drop deprecated activeColor + use Dart 3 wildcards (phase 8.8 fixup)
style(notification): use Dart 3 wildcard `(_, _)` in separatorBuilder

3. Switch Expression โ€” ์‹(expression)์œผ๋กœ์„œ์˜ switch

Dart 2 ์‹œ์ ˆ์˜ switch๋Š” statement๋ผ ๋ณ€์ˆ˜์— ์ง์ ‘ ํ• ๋‹นํ•  ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ์ฒ˜๋Ÿผ if ์‚ฌ์Šฌ์„ ์“ฐ๊ฑฐ๋‚˜, ํ•จ์ˆ˜๋กœ ๊ฐ์‹ธ์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
// Dart 2
String label;
if (status == Status.success) {
  label = '์„ฑ๊ณต';
} else if (status == Status.failure) {
  label = '์‹คํŒจ';
} else {
  label = '์ง„ํ–‰ ์ค‘';
}

Dart 3์˜ switch expression์€ ์‹(expression)์ด๋ผ ๋ณ€์ˆ˜์— ์ง์ ‘ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๊ณ , ๋ชจ๋“  ์ผ€์ด์Šค๋ฅผ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

1
2
3
4
5
final label = switch (status) {
  Status.success => '์„ฑ๊ณต',
  Status.failure => '์‹คํŒจ',
  Status.inProgress => '์ง„ํ–‰ ์ค‘',
};

break๋„ ์—†๊ณ , :์ด ์•„๋‹ˆ๋ผ => ํ™”์‚ดํ‘œ ํ‘œ๊ธฐ๋ฅผ ์”๋‹ˆ๋‹ค. ํ‘œํ˜„์‹ ํ•œ ์ค„์ด๋ผ ๊ฐ€๋…์„ฑ์ด ๋งค์šฐ ์ข‹์Šต๋‹ˆ๋‹ค.

sealed class์™€ ๊ฒฐํ•ฉ

์ง€๋‚œ ๊ธ€์—์„œ ์ •๋ฆฌํ•œ AppError sealed์™€ ๊ฒฐํ•ฉํ•˜๋ฉด ์ง„๊ฐ€๊ฐ€ ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค.

1
2
3
4
5
6
String describe(AppError e) => switch (e) {
  NetworkError(:final message) => '๋„คํŠธ์›Œํฌ ์˜ค๋ฅ˜: $message',
  NotFoundError(:final resource) => '$resource์„(๋ฅผ) ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค',
  UnauthorizedError() => '๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค',
  UnknownError(:final error) => '์•Œ ์ˆ˜ ์—†๋Š” ์˜ค๋ฅ˜: $error',
};

์ƒˆ variant๋ฅผ AppError์— ์ถ”๊ฐ€ํ•˜๋ฉด ์œ„ switch๊ฐ€ ์ปดํŒŒ์ผ ์—๋Ÿฌ๋กœ ๋ง‰ํ˜€์„œ, ์‚ฌ์šฉ์ฒ˜๋ฅผ ๊ฐ•์ œ๋กœ ์—…๋ฐ์ดํŠธํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋„๋ฉ”์ธ ๋ณ€๊ฒฝ ์‹œ ๋ˆ„๋ฝ์„ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ์žก์•„์ฃผ๋Š” ์•ˆ์ „๋ง์ด ๋ฉ๋‹ˆ๋‹ค.

if-case โ€” ๋‹จ์ผ ํŒจํ„ด ๋งค์นญ

์ „์ฒด ๋ถ„๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ผ ํŠน์ • ํŒจํ„ด๋งŒ ๋งค์นญํ•˜๊ณ  ์‹ถ์œผ๋ฉด if-case ๊ตฌ๋ฌธ์„ ์”๋‹ˆ๋‹ค.

1
2
3
if (result case Ok(:final value)) {
  print('์„ฑ๊ณต: $value');
}

์ด๊ฒŒ ๊ต‰์žฅํžˆ ์œ ์šฉํ•œ ํŒจํ„ด์ž…๋‹ˆ๋‹ค. Result<T>์—์„œ ์„ฑ๊ณต ์ผ€์ด์Šค๋งŒ ๋ถ„๊ธฐํ•˜๊ณ  ์‹คํŒจ๋Š” ๋‹ค๋ฅธ ํ๋ฆ„์œผ๋กœ ๋ณด๋‚ด๊ณ  ์‹ถ์„ ๋•Œ ํ•œ ์ค„๋กœ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

4. Guard ์กฐ๊ฑด โ€” when

ํŒจํ„ด ๋งค์นญ์— ์ถ”๊ฐ€ ์กฐ๊ฑด์„ ๋ถ™์ด๊ณ  ์‹ถ์„ ๋•Œ when ํ‚ค์›Œ๋“œ๋ฅผ ์”๋‹ˆ๋‹ค. ํŒจํ„ด์ด ๋งค์นญ๋˜๋”๋ผ๋„ when ์กฐ๊ฑด์ด false๋ฉด ๋‹ค์Œ ์ผ€์ด์Šค๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค.

1
2
3
4
5
6
7
String classify(int score) => switch (score) {
  >= 90 => 'A',
  >= 80 => 'B',
  >= 70 => 'C',
  _ when score < 0 => 'invalid',
  _ => 'F',
};

์œ„์—์„œ๋Š” relational pattern(>= 90)๋„ ์“ฐ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Dart 3๊ฐ€ ๊น”์•„ ๋†“์€ ํŒจํ„ด ์ข…๋ฅ˜๊ฐ€ ์›Œ๋‚™ ๋งŽ์•„์„œ, ๊ฐ™์€ ํ‘œํ˜„์‹ ํ•˜๋‚˜์— ์—ฌ๋Ÿฌ ํŒจํ„ด์„ ์กฐํ•ฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

5. ์‹ค์ œ ์บก์Šคํ†ค ์ฝ”๋“œ ์˜ˆ์‹œ ๋ชจ์Œ

ํ•™์Šต ์ •๋ฆฌ ์ฐจ์›์—์„œ ์บก์Šคํ†ค์—์„œ ์ด ๊ธฐ๋Šฅ๋“ค์ด ์‹ค์ œ๋กœ ์–ด๋””์— ๋“ค์–ด๊ฐ”๋Š”์ง€ ํ•œ ์ž๋ฆฌ์— ๋ชจ์•„ ๋ดค์Šต๋‹ˆ๋‹ค.

Records โ€” fl_chart ์ขŒํ‘œ

1
2
3
4
5
6
final List<({double x, double y})> weightPoints = [
  (x: 0, y: 70.5),
  (x: 1, y: 70.8),
  (x: 2, y: 71.2),
  // ...
];

Map<String, double>์ด๋‚˜ ๋ณ„๋„ ํด๋ž˜์Šค๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ€๋ณ์Šต๋‹ˆ๋‹ค.

Switch expression โ€” Result ๋งค์นญ

1
2
3
4
state = switch (result) {
  Ok(:final value) => AsyncData(value),
  Err(:final error) => AsyncError(error, StackTrace.current),
};

repository๊ฐ€ ๋ฐ˜ํ™˜ํ•œ Result<DietDay>๋ฅผ Riverpod์˜ AsyncValue๋กœ ํ•œ ์ค„์— ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

Wildcard โ€” ๋ฏธ์‚ฌ์šฉ ์ฝœ๋ฐฑ ์ธ์ž

1
2
3
4
5
ListView.separated(
  itemCount: notifications.length,
  separatorBuilder: (_, _) => const Divider(height: 1),
  itemBuilder: (_, i) => NotificationTile(item: notifications[i]),
)

if-case โ€” Stream ์ด๋ฒคํŠธ ๋ถ„๊ธฐ

1
2
3
4
5
notificationStream.listen((event) {
  if (event case PushArrived(:final notification)) {
    inAppCenter.add(notification);
  }
});

PushArrived๊ฐ€ sealed family์˜ ํ•œ variant๋ผ๋ฉด, if-case๋กœ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ unpack๋ฉ๋‹ˆ๋‹ค.

6. ์ •๋ฆฌ / ๋‹ค์Œ ํ•™์Šต ๊ณ„ํš

Dart 3์˜ records / patterns / switch expression์€ ์ฒ˜์Œ ๋ดค์„ ๋•Œ๋Š” โ€œKotlin์ด๋‚˜ Rust ๊ฐ™์€ ๊ฒƒโ€์ด๋ผ๊ณ ๋งŒ ๋А๊ผˆ๋Š”๋ฐ, ์‹ค์ œ๋กœ ์ฝ”๋“œ์— ๋ฐ•์•„ ๋ณด๋‹ˆ ๋‹ค์Œ ํšจ๊ณผ๊ฐ€ ๋ถ„๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค.

  1. ์ž„์‹œ ๋ฐ์ดํ„ฐ ๋ฌถ์Œ์˜ ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ๊ฐ€ ์‚ฌ๋ผ์ง‘๋‹ˆ๋‹ค. record๋กœ ๋.
  2. sealed class์™€ ๊ฒฐํ•ฉํ•  ๋•Œ exhaustiveness ๊ฒ€์‚ฌ๊ฐ€ ์ปดํŒŒ์ผ๋Ÿฌ ์•ˆ์ „๋ง์ด ๋ฉ๋‹ˆ๋‹ค.
  3. ์ฝœ๋ฐฑ ์‹œ๊ทธ๋‹ˆ์ฒ˜๊ฐ€ ๊น”๋”ํ•ด์ง‘๋‹ˆ๋‹ค. _๋กœ ๋ฌด๊ด€ ์ธ์ž๋ฅผ ๋ช…์‹œํ•˜๋ฉด ์˜๋„๊ฐ€ ๋ถ„๋ช…ํžˆ ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ ํ•™์Šต์€ ์บก์Šคํ†ค ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ํ•œ ๋ฒˆ ํ›‘์œผ๋ฉด์„œ ๋ฐœ๊ฒฌํ•œ ๋˜ ๋‹ค๋ฅธ Dart ๋ฉ”ํƒ€ ํŒจํ„ด โ€” Extension methods, Mixin, build_runner๋ฅผ ํ†ตํ•œ ์ฝ”๋“œ ์ƒ์„ฑ์„ ์ •๋ฆฌํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ํ•™๊ธฐ ๋งˆ์ง€๋ง‰ ํ•™์Šต ๋…ธํŠธ๊ฐ€ ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.


๐Ÿ“Œ ์š”์•ฝ

Dart 3์˜ records / patterns / switch expression์€ ์บก์Šคํ†ค ์ฝ”๋“œ์— ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๋…น์•„๋“  ํ•ต์‹ฌ ๊ธฐ๋Šฅ๋“ค์ž…๋‹ˆ๋‹ค. records๋Š” ์ž„์‹œ ๋ฐ์ดํ„ฐ ๋ฌถ์Œ(์ฐจํŠธ ์ขŒํ‘œ ๋“ฑ)์—์„œ ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ๋ฅผ ์—†์• ๊ณ , switch expression์€ sealed class์™€ ๊ฒฐํ•ฉํ•ด ๋ชจ๋“  variant๋ฅผ ๋ง๋ผํ•˜์ง€ ์•Š์œผ๋ฉด ์ปดํŒŒ์ผ ์—๋Ÿฌ๋ฅผ ๋„์›Œ ๋„๋ฉ”์ธ ํ™•์žฅ ์‹œ ์•ˆ์ „๋ง์ด ๋ฉ๋‹ˆ๋‹ค. _ wildcard ํŒจํ„ด์€ ์ฝœ๋ฐฑ์˜ ๋ฏธ์‚ฌ์šฉ ์ธ์ž๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ‘œํ˜„ํ•ด ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ณ , if-case๋กœ ๋‹จ์ผ ํŒจํ„ด ๋งค์นญ์ด ํ•œ ์ค„์— ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ ์€ ๋ฌธ๋ฒ• ์ถ”๊ฐ€๋กœ ํ‘œํ˜„๋ ฅ์ด ํฌ๊ฒŒ ๋Š˜์–ด๋‚œ, Dart 3์—์„œ ๊ฐ€์žฅ ๋งŒ์กฑ์Šค๋Ÿฌ์šด ๋ณ€ํ™”์˜€์Šต๋‹ˆ๋‹ค.

This post is licensed under CC BY 4.0 by the author.