๋ฐ˜์‘ํ˜•

Dart์™€ JavaScript๋Š” ๋งŽ์€ ๊ฐœ๋…์„ ๊ณต์œ ํ•œ๋‹ค. Dart ์—ญ์‹œ ์ด๋ฒคํŠธ ๋ฃจํ”„์—์„œ ์‹คํ–‰๋˜๊ณ , ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•œ Future๋ผ๋Š” ๊ฐœ๋…์ด ์กด์žฌํ•œ๋‹ค. Future๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ Promise์™€ ๋น„์Šทํ•˜๋‹ค. Dart๋Š” ์ •์  ํƒ€์ž… ์–ธ์–ด์ด๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‚ฌ์šฉํ•œ ๊ฒฝํ—˜์ด ์žˆ๋‹ค๋ฉด Dart๋ฅผ ๋” ์‰ฝ๊ฒŒ ๋ฐฐ์šธ ์ˆ˜ ์žˆ๋‹ค.

 

Dart์™€ JavaScript์˜ ๋‹ค๋ฅธ ์ ๊ณผ ๋น„์Šทํ•œ ์ ์„ Learning Dart as a JavaScript developer ํŽ˜์ด์ง€์— ์ž์„ธํžˆ ์„ค๋ช…๋ผ ์žˆ์–ด์„œ ์ •๋ฆฌํ•ด๋ดค๋‹ค.

 

 

Conventions and linting


  • Dart ํŒ€์—์„œ ๊ณต์‹์ ์œผ๋กœ ์ฝ”๋“œ ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ์™€ Lint ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
  • dart fix๋ฅผ ํ†ตํ•ด ์ฝ”๋“œ ์ด์Šˆ๋ฅผ ๋ฐœ๊ฒฌํ•˜๊ณ  ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • dart format์„ ํ†ตํ•ด ์ฝ”๋“œ๋ฅผ ํฌ๋งคํŒ…ํ•  ์ˆ˜ ์žˆ๋‹ค

 

 

Built-in types


  • Dart๋Š” ์ •์  ํƒ€์ž… ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ€์ˆ˜์™€ ํ‘œํ˜„์‹ ํƒ€์ž…์„ ์ปดํŒŒ์ผ ์‹œ์ ์— ๊ฒฐ์ •ํ•œ๋‹ค.
  • Dart์˜ ๋นŒํŠธ์ธ ํƒ€์ž… :
    • Numbers (num, int, double)
    • Strings (String)
    • Booleans (bool)
    • Lists (List) — ๋ฐฐ์—ด
    • Sets (Set) — ์ค‘๋ณต๋˜์ง€ ์•Š๋Š” ์œ ์ผํ•œ ์š”์†Œ๋“ค์˜ ์ง‘ํ•ฉ(์ˆœ์„œ ๋ณด์žฅ ์•ˆํ•จ)
    • Maps (Map) — ํ‚ค-๊ฐ’ ์Œ์„ ์ €์žฅํ•˜๋Š” ์ปฌ๋ ‰์…˜(๊ฐ์ฒด์™€ ๋น„์Šท)
    • Symbols (Symbol)
    • null (Null)
  • Dart์—์„  ์›์‹œ ํƒ€์ž…์ด ์—†๋‹ค. ๋ชจ๋“  ๊ฐ’์€ ๊ฐ์ฒด๋‹ค.
  • number, boolean, null ํƒ€์ž…์€ ์ •๊ทœํ™” ๊ณผ์ •์„ ํ†ตํ•ด ๋ฉ”๋ชจ๋ฆฌ ์ƒ์— ์˜ค์ง ํ•˜๋‚˜์˜ ๊ฐ์ฒด๋กœ๋งŒ ์กด์žฌํ•œ๋‹ค. ์˜ˆ๋ฅผ๋“ค์–ด ์ˆซ์ž 1์„ ๋‹ค๋ฅธ ๋ณ€์ˆ˜์—์„œ ์—ฌ๋Ÿฌ ๋ฒˆ ์‚ฌ์šฉํ•ด๋„ ๋ฉ”๋ชจ๋ฆฌ์—” ์˜ค์ง ํ•˜๋‚˜์˜ int ๊ฐ์ฒด๋กœ๋งŒ ์ €์žฅ๋œ๋‹ค.
  • == ์—ฐ์‚ฐ์ž๋Š” ๋…ผ๋ฆฌ์  ๋™๋“ฑ์„ฑ(๊ฐ™์€ ๊ฐ’์„ ๊ฐ€์ง€๋Š”์ง€)์„ ๋น„๊ตํ•˜๊ณ , identical() ํ•จ์ˆ˜๋Š” ์ฐธ์กฐ ๋™๋“ฑ์„ฑ(๊ฐ™์€ ์ธ์Šคํ„ด์Šค์ธ์ง€)์„ ๋น„๊ตํ•œ๋‹ค.

 

Numbers

 

Dart๋Š” ์ˆซ์ž๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ 3๊ฐ€์ง€ ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด ์žˆ๋‹ค

  1. int : ์†Œ์ˆ˜๋ถ€๊ฐ€ ์—†๋Š” ์ˆซ์ž(์ •์ˆ˜)
  2. double : 64๋น„ํŠธ(๋ฐฐ์ •๋ฐ€๋„) ๋ถ€๋™ ์†Œ์ˆ˜์  ์ˆซ์ž(์‹ค์ˆ˜)
  3. num : int์™€ double์˜ ์ƒ์œ„ ํƒ€์ž…. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ number ํƒ€์ž…๊ณผ ๋™์ผ

 

Dart๋Š” ์ˆซ์ž๋„ ๊ฐ์ฒด๋กœ ๊ฐ„์ฃผํ•˜๋ฏ€๋กœ, ์ˆซ์ž์—์„œ ๋ฐ”๋กœ ๊ด€๋ จ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

// JS
const rounded = math.round(2.5);
// Dart
var rounded = 2.5.round();

 

String

๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์„ ์ž‘์„ฑํ•˜๋ ค๋ฉด ๋”ฐ์˜ดํ‘œ ' ํ˜น์€ ์Œ๋”ฐ์˜ดํ‘œ " ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ํŠน์ˆ˜ ๋ฌธ์ž ์ด์Šค์ผ€์ดํ”„๋Š” ๋ฐฑ์Šฌ๋ž˜์‹œ \ ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

final singleQuotes = 'I\'m learning Dart'; // I'm learning Dart
final doubleQuotes = "Escaping the \" character"; // Escaping the " character
final dollarEscape = 'The price is \$3.14.'; // The price is $3.14.
final backslashEscape = 'The Dart string escape character is \\.';
final unicode = '\u{1F60E}'; // ๐Ÿ˜Ž,  Unicode scalar U+1F60E

 

๋ฌธ์ž์—ด์— ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•  ๋• ${ํ‘œํ˜„์‹} ํ˜•ํƒœ๋กœ ์‚ฌ์šฉํ•œ๋‹ค. ๋‹จ์ผ ์‹๋ณ„์ž์ผ ๋• ์ค‘๊ด„ํ˜ธ๋ฅผ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ๋‹ค.

int a = 5;
int b = 3;
var str = 'The sum of $a and $b is ${a + b}.'

 

Dart์—์„  ๋ฌธ์ž์—ด์ด ์—ฌ๋Ÿฌ ์ค„์— ๊ฑธ์ณ ์žˆ๋Š” ๊ฒฝ์šฐ ์ธ์ ‘ํ•œ ๋ฌธ์ž์—ด ๋ฆฌํ„ฐ๋Ÿด์„ ๋ชจ๋‘ ์—ฐ๊ฒฐํ•œ๋‹ค.

final s1 = 'String '
    'concatenation'
    " even works over line breaks.";

print(s1); // String concatenation even works over line breaks.

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ๋ฒกํ‹ฑ(`)์„ ์ด์šฉํ•ด ์—ฌ๋Ÿฌ ์ค„์˜ ๋ฌธ์ž์—ด์„ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Dart์—์„  ๋”ฐ์˜ดํ‘œ 3๊ฐœ(''' ํ˜น์€ """)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

final s2 = '''
You can create
multiline strings like this one.
''';

 

Equality

Dart๋Š” ๋‘ ๋ฌธ์ž์—ด์ด ๋™์ผํ•œ ์ฝ”๋“œ ์œ ๋‹› ์‹œํ€€์Šค๋ฅผ ํฌํ•จํ•˜๋ฉด ๊ฐ™์€ ๊ฐ’์œผ๋กœ ๊ฐ„์ฃผํ•œ๋‹ค. ๋‘ ๋ฌธ์ž์—ด์ด ๋™์ผํ•œ ์‹œํ€€์Šค์ธ์ง€ ํ™•์ธํ•˜๋ ค๋ฉด equal-to == ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

final s1 = 'Hello '
    'World';
print(s1 == 'Hello World'); // true

 

Booleans

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋‹คํŠธ์˜ ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์€ ์ด์ง„ ์กฐ๊ฑด(์ฐธ/๊ฑฐ์ง“)์„ ํ‘œํ˜„ํ•œ๋‹ค. true, false ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ x < 5 ๊ฐ™์€ ํ‘œํ˜„์‹์„ ์‚ฌ์šฉํ•ด์„œ ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

var isLoading = false;

 

 

Variables


Dart์˜ ๋ชจ๋“  ๋ณ€์ˆ˜๋Š” ํƒ€์ž…์ด ์žˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ let, const ์ฒ˜๋Ÿผ ๋ธ”๋ก ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ€์ง„๋‹ค. ๋ณ€์ˆ˜ ํƒ€์ž…์„ ์ง์ ‘ ์ •์˜ํ•˜๊ฑฐ๋‚˜, Dart ๋ถ„์„๊ธฐ๊ฐ€ ํƒ€์ž…์„ ์ถ”๋ก ํ•˜๋„๋ก ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

// ๋ณ€์ˆ˜ ์„ ์–ธ๊ณผ ๋™์‹œ์— ์ดˆ๊ธฐํ™”ํ•˜๋ฉด Dart๊ฐ€ ํƒ€์ž…์„ ์ถ”๋ก ํ•œ๋‹ค
var name = 'bob';
// Error! ์ถ”๋ก ํ•œ ํƒ€์ž…๋งŒ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค
name = 5;

 

์ดˆ๊ธฐ ๊ฐ’์„ ์ œ๊ณตํ•˜์ง€ ์•Š๊ฑฐ๋‚˜ ํƒ€์ž…์„ ๋ณ„๋„๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  ํƒ€์ž…์„ ํ—ˆ์šฉํ•˜๋Š” dynamic์œผ๋กœ ์ถ”๋ก ๋œ๋‹ค. dynamic์€ catch-all ํƒ€์ž…์œผ๋กœ, TypeScript์˜ any์™€ ๋น„์Šทํ•˜๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

// dynamic type์œผ๋กœ ์ถ”๋ก 
var name; 

name = 'bob'; // OK
name = 5; // OK

 

Final and const โญ๏ธ

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ Dart ๋ชจ๋‘ const๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์ž‘๋™ ๋ฐฉ์‹์ด ์กฐ๊ธˆ ๋‹ค๋ฅด๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ const๋Š” Dart์—์„œ final ํ‚ค์›Œ๋“œ์™€ ๋” ์œ ์‚ฌํ•˜๋‹ค. final๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋Š” ํ•œ ๋ฒˆ ์ดˆ๊ธฐ๋˜๋ฉด ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†์œผ๋ฉฐ, ๋ณ€์ˆ˜์˜ ๊ฐ’์€ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ๊ฒฐ์ •๋œ๋‹ค.

 

Dart์˜ const๋Š” ์ปดํŒŒ์ผ ์‹œ์ ์— ์ƒ์„ฑ๋˜๋Š” ๋ถˆ๋ณ€ ๊ฐ’์œผ๋กœ ์‚ฌ์ด๋“œ ์ดํŽ™ํŠธ๊ฐ€ ์—†๋Š” ํŠน์ง•์ด ์žˆ๋‹ค. ์ •๋ฆฌํ•˜๋ฉด final์€ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์—, const๋Š” ์ปดํŒŒ์ผ ์‹œ์ ์— ๊ฒฐ์ •๋˜๋Š” ๋ถˆ๋ณ€๊ฐ’์ด๋ผ๊ณ  ๋ณด๋ฉด ๋œ๋‹ค. 

 

์ƒ์ˆ˜ ๋ณ€์ˆ˜(constant variables) : const ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์„ ์–ธํ•œ ๋ณ€์ˆ˜. ์ƒ์ˆ˜ ๋ณ€์ˆ˜๋Š” ๋ฐ˜๋“œ์‹œ ์ƒ์ˆ˜ ๊ฐ’์„ ํฌํ•จํ•ด์•ผ ํ•œ๋‹ค. ์ƒ์ˆ˜ ๊ฐ’์ด๋ž€ ์ปดํŒŒ์ผ ์‹œ์ ์— ๊ฒฐ์ •๋˜๋Š” ๊ฐ’์œผ๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋Š” ๊ฐ’์„ ์˜๋ฏธํ•œ๋‹ค.

const int a = 10; // ๊ฐ’์ด 10์œผ๋กœ ๊ณ ์ •๋œ ์ƒ์ˆ˜ ๋ณ€์ˆ˜

 

๋น„์ƒ์ˆ˜ ๋ณ€์ˆ˜(non-constant variables) : final ๋˜๋Š” var๋กœ ์„ ์–ธํ•œ ๋ณ€์ˆ˜. ๋น„์ƒ์ˆ˜ ๋ณ€์ˆ˜๋„ ์ƒ์ˆ˜ ๊ฐ’์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋‹ค. ์ƒ์ˆ˜ ๊ฐ’์„ ํฌํ•จํ•˜๋Š” ๊ฒฝ์šฐ์—” const ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๊ฐ’์„ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.

final int b = 20; // ์ƒ์ˆ˜ ๊ฐ’ 20์„ ํฌํ•จํ•œ ๋น„์ƒ์ˆ˜ ๋ณ€์ˆ˜
var c = const [1, 2, 3]; // ์ƒ์ˆ˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ํฌํ•จํ•œ ๋น„์ƒ์ˆ˜ ๋ณ€์ˆ˜

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ const๋Š” ๋ณ€์ˆ˜์˜ ์žฌํ• ๋‹น์„ ๋ง‰์ง€๋งŒ, ๊ฐ์ฒด ํ•„๋“œ์˜ ์ˆ˜์ •์€ ํ—ˆ์šฉํ•œ๋‹ค. ๋ฐ˜๋ฉด Dart์˜ const๋Š” ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์™„์ „ํ•œ ๋ถˆ๋ณ€์œผ๋กœ ๋งŒ๋“ค์–ด ์žฌํ• ๋‹น์€ ๋ฌผ๋ก  ๊ฐ์ฒด ํ•„๋“œ๋„ ์ˆ˜์ •๋„ ๊ธˆ์ง€ํ•œ๋‹ค.

 

 

Null safety


์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๋‹ค๋ฅด๊ฒŒ Dart๋Š” null safety๋ฅผ ์ง€์›ํ•œ๋‹ค. null safety๋Š” null ์ฐธ์กฐ๋กœ ์ธํ•œ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋Šฅ์ด๋‹ค. Dart์—์„  ๋ชจ๋“  ๋ณ€์ˆ˜์™€ ๊ฐ์ฒด๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ null์„ ๊ฐ€์งˆ ์ˆ˜ ์—†๋‹ค(non-nullable).

 

์ปดํŒŒ์ผ ํƒ€์ž„์—(์ฝ”๋“œ ์ž‘์„ฑ ์‹œ์ ) null ์ฐธ์กฐ ์˜ˆ์™ธ๋ฅผ ํฌ์ฐฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ณ€์ˆ˜๊ฐ€ null ๊ฐ’์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ์„ ๋‚˜ํƒ€๋‚ด๋ ค๋ฉด ํƒ€์ž… ์„ ์–ธ์— ?๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. Dart์—์„œ ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜์ง€ ์•Š์œผ๋ฉด(๊ฐ’์„ ํ• ๋‹นํ•˜์ง€ ์•Š์œผ๋ฉด) null ๊ฐ’์„ ๊ฐ€์ง„๋‹ค(JS๋Š” undefined).

int? nullableInt; // int? nullableInt = null; ์™€ ๋™์ผ
print(nullableInt); // null

 

Dart๋Š” null์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์ฒ˜๋Ÿผ null ํ• ๋‹น ์—ฐ์‚ฐ์ž ??=, null ๋ณ‘ํ•ฉ ์—ฐ์‚ฐ์ž ??, ์˜ต์…”๋„ ์ฒด์ด๋‹ ์—ฐ์‚ฐ์ž ?.๋ฅผ ์ง€์›ํ•œ๋‹ค. Nullable ๋ณ€์ˆ˜๋‚˜ ํ‘œํ˜„์‹์ด null์ด ์•„๋‹˜์„ ๋‹จ์–ธํ•˜๊ธฐ ์œ„ํ•ด ! ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์ปดํŒŒ์ผ๋Ÿฌ์˜ null ๊ฒ€์‚ฌ ์˜ค๋ฅ˜๋ฅผ ์–ต์ œํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

int? a = 5;

// nullable ํƒ€์ž… a๋ฅผ non-nullable ํƒ€์ž…์ธ b์— ํ• ๋‹น ํ•  ์ˆ˜ ์—†๋‹ค.
int b = a; 
// ! ์—ฐ์‚ฐ์ž๋กœ a๋ฅผ non-nulalble ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ–ˆ์œผ๋ฏ€๋กœ ํ• ๋‹น ๊ฐ€๋Šฅ
int b = a!;

 

Functions

์•ฝ๊ฐ„์˜ ํ•จ์ˆ˜ ์„ ์–ธ ๋ฌธ๋ฒ• ์ฐจ์ด๋ฅผ ์ œ์™ธํ•˜๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜์™€ ๊ฑฐ์˜ ๋น„์Šทํ•˜๊ฒŒ ์ž‘๋™ํ•œ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์ฒ˜๋Ÿผ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ, ํด๋ž˜์Šค ํ•„๋“œ, ๋กœ์ปฌ ์Šค์ฝ”ํ”„ ๋“ฑ ๊ฑฐ์˜ ๋ชจ๋“  ๊ณณ์—์„œ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค.

// ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ
int multiply(int a, int b) {
  return a * b;
}

// ๋กœ์ปฌ ์Šค์ฝ”ํ”„
void main() {
  int multiply(int a, int b) {
    return a * b;
  }

  print(multiply(3, 4));
}

 

Arrow syntax

Dart ์—์„œ๋„ ํ•จ์ˆ˜์˜ ํ™”์‚ดํ‘œ => ๊ตฌ๋ฌธ์„ ์ง€์›ํ•˜์ง€๋งŒ, ๋‹จ์ผ ํ‘œํ˜„์‹ ๋˜๋Š” ๋ฆฌํ„ด๋ฌธ์„ ํฌํ•จํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ์•„๋ž˜ ๋‘ isNoble ํ•จ์ˆ˜๋Š” ๋™์ผํ•˜๋‹ค.

// ์ผ๋ฐ˜ ํ•จ์ˆ˜
bool isNoble(int atomicNumber) {
  return _nobleGases[atomicNumber] != null;
}

// ํ™”์‚ดํ‘œ ํ•จ์ˆ˜
bool isNoble(int atomicNumber) => _nobleGases[atomicNumber] != null;

 

Parameters

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ˆœ์„œ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ „๋‹ฌํ•˜๋ฉฐ, ์ด๋ฅผ ์œ„์น˜ ๋งค๊ฐœ๋ณ€์ˆ˜(Positional Parameters)๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค.

function multiply(a, b) {
  return a * b;
}

multiply(3, 5); // 15

 

Dart์—์„  ์œ„์น˜ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๋„ค์ž„๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜(Named Parameters)๋ฅผ ๋ชจ๋‘ ์ง€์›ํ•œ๋‹ค. ๋„ค์ž„๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ ํŒŒ๋ผ๋ฏธํ„ฐ ์ˆœ์„œ๋ฅผ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๋„ค์ž„๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ค‘๊ด„ํ˜ธ {} ๋ฅผ ์ด์šฉํ•ด ์ •์˜ํ•˜๋ฉฐ, required ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ์„ ํƒ์ ์ด๋‹ค. ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” null safety๋ฅผ ์œ„ํ•ด ๊ธฐ๋ณธ๊ฐ’์„ ํ• ๋‹นํ•˜๊ฑฐ๋‚˜ nullable๋กœ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค.

multiply({required int a, required int b}) {
  return a * b;
}

multiply(a: 3, b: 5); // 15
multiply(b: 5, a: 3); // 15

 

๋„ค์ž„๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•„์ˆ˜ ์œ„์น˜ ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ, ์ด๋• ์œ„์น˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋’ค์— ์œ„์น˜ํ•ด์•ผ ํ•œ๋‹ค.

multiply(bool x, {required int a, int b = 5, int? c}) { ... }

multiply(false, a: 3); // OK
multiply(false, a: 3, b: 9); // OK
multiply(false, c: 9, a: 3, b: 2); // OK

 

์œ„์น˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ ํƒ์ ์œผ๋กœ ๋งŒ๋“ค ๋• [] ๋Œ€๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํ•ญ์ƒ ํ•„์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜ ๋’ค์— ์œ„์น˜ํ•ด์•ผ ํ•œ๋‹ค. ์ฐธ๊ณ ๋กœ ์œ„์น˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋‘ ํ•„์ˆ˜(required)๋‹ค.

// b์— ๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•˜๊ณ  c์—” nullable๋กœ ์ง€์ •ํ–ˆ์œผ๋ฏ€๋กœ ์œ ํšจ
multiply(int a, [int b = 5, int? c]) { ... }

// ํ•„์ˆ˜ ๋งค๊ฐœ๋ณ€์ˆ˜ c๊ฐ€ ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜ b ๋’ค์— ์œ„์น˜ํ•˜๋ฏ€๋กœ ์œ ํšจํ•˜์ง€ ์•Š์Œ
multiply(int a, [int b = 5], int c) { ... }

// ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜ b, c๊ฐ€ ๊ธฐ๋ณธ๊ฐ’ ํ˜น์€ nullable๋กœ ์ง€์ •๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ ์œ ํšจํ•˜์ง€ ์•Š์Œ
multiply(int a, [int b, int c]) { ... }

 

์•„๋ž˜๋Š” ์„ ํƒ์  ์œ„์น˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง„ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์˜ˆ์‹œ.

multiply(int a, [int b = 5, int? c]) { ... }

multiply(3); // OK
multiply(3, 5); // OK
multiply(3, 5, 7); // OK

 

First-class functions

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Dart๋Š” ํ•จ์ˆ˜๋ฅผ ์ผ๊ธ‰ ๊ฐ์ฒด(first-class)๋กœ ์ทจ๊ธ‰ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์˜ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ๋ณ€์ˆ˜์— ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค.

void printElement(int element) {
  print(element);
}

var list = [1, 2, 3];
list.forEach(printElement);

 

Anonymous functions

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ Dart ๋ชจ๋‘ ์ต๋ช… ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•œ๋‹ค.

var blockFunc = optionalCallback ?? (int a, int b) { return a * b; };    

var singleFunc = (int a, int b) => a * b;

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์ฒ˜๋Ÿผ ์ต๋ช… ํ•จ์ˆ˜๋ฅผ ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฐธ๊ณ ๋กœ Dart์˜ map() ๋ฉ”์„œ๋“œ๋Š” Iterable์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , toList() ๋ฉ”์„œ๋“œ๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์„ List๋กœ ๋ณ€ํ™˜ํ•œ๋‹ค.

[1, 2, 3].map((e) => e + 3).toList();

 

Generator functions

Dart ์—ญ์‹œ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ์ง€์›ํ•œ๋‹ค. ํ•จ์ˆ˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๋’ค์— sync* ํ‚ค์›Œ๋“œ๋ฅผ ๋ถ™์ด๋ฉด ์ดํ„ฐ๋Ÿฌ๋ธ”์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜์—์„œ yield ํ‚ค์›Œ๋“œ๋ฅผ ์ด์šฉํ•˜์—ฌ ํ˜„์žฌ ํ•ญ๋ชฉ์„ ์ดํ„ฐ๋Ÿฌ๋ธ”์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

Iterable<int> naturalsTo(int n) sync* {
  int k = 0;
  while (k < n) {
    yield k++;
  }
}

print(naturalsTo(5).toList()); // [0, 1, 2, 3, 4]

 

yield* ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋‹ค๋ฅธ ์ดํ„ฐ๋Ÿฌ๋ธ”์˜ ๋ชจ๋“  ๊ฐ’์„ ํ•œ ๋ฒˆ์— ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

Iterable<int> doubleNaturalsTo(int n) sync* {
  int k = 0;
  while (k < n) {
    yield* [k, k];
    k++;
  }
}

print(doubleNaturalsTo(3).toList()); // [0, 0, 1, 1, 2, 2]

 

 

Statements


Control flow (if/else, for, while, switch)

Dart์˜ for-in ๋ฌธ์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ for-of ์ฒ˜๋Ÿผ ์ž‘๋™ํ•œ๋‹ค

for (final i in [1, 2, 3]) {
  print(i); // 1, 2, 3
}

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ switch ๋ฌธ์€ fall-through ๋™์ž‘์ด ์ ์šฉ๋ผ์„œ case์— break, return ๋ฌธ์ด ์—†์œผ๋ฉด ๋‹ค์Œ case๋ฅผ ์ด์–ด์„œ ์‹คํ–‰ํ•œ๋‹ค. ๋ฐ˜๋ฉด Dart๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ fall-through๋ฅผ ํ—ˆ์šฉํ•˜์ง€ ์•Š์œผ๋ฉฐ, continue ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ case ๋ณธ๋ฌธ์ด ๋น„์–ด์žˆ์„ ๋•Œ๋งŒ ํ—ˆ์šฉํ•œ๋‹ค.

// JS
const value = 2;

switch (value) {
  case 1:
    console.log("Case 1");
  case 2:
    console.log("Case 2");
  case 3:
    console.log("Case 3");
  default:
    console.log("Default case");
}

// ์ถœ๋ ฅ: Case 2, Case 3, Default case
// Dart
var value = 2;

switch (value) {
  case 1: // case ๋ณธ๋ฌธ์ด ๋น„์–ด์žˆ์œผ๋ฏ€๋กœ ๋‹ค์Œ case ์‹คํ–‰
  case 2:
    print("Case 1 or 2");
  case 3:
    print("Case 3");
  default:
    print("Default case");
}

// ์ถœ๋ ฅ: Case 1 or 2

 

Dart์˜ switch ๋ฌธ์—์„  case์— ๋ ˆ์ด๋ธ”์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, continue ๋ฌธ์—์„œ ๋ช…์‹œํ•œ case ๋ ˆ์ด๋ธ”๋กœ ๋ฐ”๋กœ ์ด๋™(์ผ์ข…์˜ ์ ํ”„)ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

var value = 1;

switch (value) {
  case 1:
    print('Case 1');
    continue three;
  case 2:
    print('Case 2');
  three:
  case 3:
    print('Case 3');
}

// ์ถœ๋ ฅ: Case 1, Case 3

 

Operators

Dart๋Š” operator ํ‚ค์›Œ๋“œ๋กœ ๊ธฐ์กด ์—ฐ์‚ฐ์ž๋ฅผ ์˜ค๋ฒ„๋กœ๋”ฉ ํ•  ์ˆ˜ ์žˆ๋‹ค(์—ฐ์‚ฐ์ž ์žฌ์ •์˜).

class Vector {
  // ํด๋ž˜์Šค ํ•„๋“œ ์„ ์–ธ
  final double x;
  final double y;
  final double z;

  // ์ƒ์„ฑ์ž ์ดˆ๊ธฐํ™”
  Vector(this.x, this.y, this.z);

  // ์—ฐ์‚ฐ์ž ์˜ค๋ฒ„๋กœ๋”ฉ - ๋ฐ˜ํ™˜ํƒ€์ž… operator ์—ฐ์‚ฐ์ž(์ธ์žํƒ€์ž… ์ธ์ž) { ์˜ค๋ฒ„๋กœ๋”ฉ ๋กœ์ง }
  Vector operator +(Vector other) {
    return Vector(x + other.x, y + other.y, z + other.z);
  }
}

void main() {
  var v1 = Vector(1, 2, 3);
  var v2 = Vector(4, 5, 6);
  // v1์˜ ์˜ค๋ฒ„๋กœ๋”ฉ๋œ + ์—ฐ์‚ฐ์ž ํ˜ธ์ถœ. other ์ธ์ž์—” v2๊ฐ€ ์ „๋‹ฌ๋˜๊ณ  ์ƒˆ๋กœ์šด Vector ์ธ์Šคํ„ด์Šค ๋ฐ˜ํ™˜
  var v3 = v1 + v2;
  // ์ถœ๋ ฅ: 5.0, 7.0, 9.0
  print("${v3.x}, ${v3.y}, ${v3.z}"); 
}

 

๋‘ ์–ธ์–ด์˜ ์‚ฐ์ˆ  ์—ฐ์‚ฐ์ž๋Š” ๋™์ผํ•˜์ง€๋งŒ Dart๋Š” ๋‚˜๋ˆ—์…ˆ์˜ ๊ฒฐ๊ณผ๋ฅผ ์ •์ˆ˜๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ~/ ์—ฐ์‚ฐ์ž๊ฐ€ ์กด์žฌํ•œ๋‹ค.

์˜๋ฏธ JavaScript ์—ฐ์‚ฐ์ž Dart ์—ฐ์‚ฐ์ž
๋ง์…ˆ + +
๋บ„์…ˆ - -
๋‹จํ•ญ ๋งˆ์ด๋„ˆ์Šค, ๋ถ€์ • -expr -expr
๊ณฑ์…ˆ * *
๋‚˜๋ˆ—์…ˆ / /
์ •์ˆ˜ ๋‚˜๋ˆ—์…ˆ   ~/
๋‚˜๋จธ์ง€ ์—ฐ์‚ฐ % %
์ „์œ„ ์ฆ๊ฐ ++x ++x
ํ›„์œ„ ์ฆ๊ฐ x++ x++
์ „์œ„ ๊ฐ์†Œ --x --x
ํ›„์œ„ ๊ฐ์†Œ x-- x--

 

print(25 == 50.4 ~/ 2); // true

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ Dart์˜ ๋™๋“ฑ/๊ด€๊ณ„ ์—ฐ์‚ฐ์ž๋Š” ๊ฑฐ์˜ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค. Dart์—์„  ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์ฒ˜๋Ÿผ ๊ฐ•์ œ๋กœ ํƒ€์ž…์„ ๋ณ€ํ™˜ํ•œ ํ›„ ๋น„๊ตํ•˜๋Š” ์ถ”์ƒ์ (๋Š์Šจํ•œ) ๋น„๊ต ์—ฐ์‚ฐ์ž๊ฐ€ ์—†๊ณ  ํ•ญ์ƒ ํƒ€์ž…์„ ๊ณ ๋ คํ•˜์—ฌ ๊ฐ’์„ ๋น„๊ตํ•œ๋‹ค.

์˜๋ฏธ JavaScript ์—ฐ์‚ฐ์ž Dart ์—ฐ์‚ฐ์ž
์—„๊ฒฉํ•œ ๋™๋“ฑ === ==
์ถ”์ƒ์  ๋™๋“ฑ ==  
์—„๊ฒฉํ•œ ๋ถ€๋“ฑ !== !=
์ถ”์ƒ์  ๋ถ€๋“ฑ !=  
ํฌ๋‹ค > >
์ž‘๋‹ค < <
ํฌ๊ฑฐ๋‚˜ ๊ฐ™๋‹ค >= >=
์ž‘๊ฑฐ๋‚˜ ๊ฐ™๋‹ค <= <=

 

ํƒ€์ž… ํ…Œ์ŠคํŠธ ์—ฐ์‚ฐ์ž๋Š” ๋‘ ์–ธ์–ด๊ฐ€ ์‚ด์ง ๋‹ค๋ฅด๋‹ค. Dart์˜ is ์—ฐ์‚ฐ์ž๋Š” ํŠน์ • ํƒ€์ž…์˜ ์ธ์Šคํ„ด์Šค์ธ์ง€ ํ˜น์€ ํ•ด๋‹น ํƒ€์ž…์„ ๊ตฌํ˜„ํ–ˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค(๋Ÿฐํƒ€์ž„ ํƒ€์ž… ๊ฒ€์‚ฌ). ์˜ˆ๋ฅผ๋“ค์–ด Dart์—์„  ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ Object๋ฅผ ์ƒ์† ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์— {} is Object ํ‘œํ˜„์‹์€ true๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์˜๋ฏธ JavaScript ์—ฐ์‚ฐ์ž Dart ์—ฐ์‚ฐ์ž
ํƒ€์ž… ์บ์ŠคํŠธ   x as T
๊ฐ์ฒด๊ฐ€ ์ง€์ •๋œ ํƒ€์ž…์ธ์ง€ ํ™•์ธ x instanceof T x is T
๊ฐ์ฒด๊ฐ€ ์ง€์ •๋œ ํƒ€์ž…์ด ์•„๋‹Œ์ง€ ํ™•์ธ !(x instanceof T) x is! T

 

var num = 42;
// num์ด int ํƒ€์ž…์ธ์ง€ ํ™•์ธ
if (num is int) { /* ... */ }

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ Dart์˜ ๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž๋Š” ๋™์ผํ•˜์ง€๋งŒ ์กฐ๊ฑด๋ฌธ์—์„œ ๊ฐ’์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐฉ์‹์ด ๋‹ค๋ฅด๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  ๋ชจ๋“  ๊ฐ’์„ ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์œผ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๋นˆ ๋ฌธ์ž์—ด "" ๊ณผ ์ˆซ์ž 0 ์€ falsy ๊ฐ’์œผ๋กœ ๊ฐ„์ฃผ๋ผ์„œ false๋กœ ํ‰๊ฐ€๋œ๋‹ค. ๋ฐ˜๋ฉด Dart์—์„  ์กฐ๊ฑด๋ฌธ๊ณผ ๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž์˜ ํ”ผ์—ฐ์‚ฐ์ž๋Š” ์˜ค์ง ๋ถˆ๋ฆฌ์–ธ ํƒ€์ž…๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์˜๋ฏธ JavaScript ์—ฐ์‚ฐ์ž Dart ์—ฐ์‚ฐ์ž
NOT !x !x
OR || ||
AND && &&

 

var x = "foo";

// x๋Š” ๋ถˆ๋ฆฌ์–ธ ํƒ€์ž…์ด ์•„๋‹ˆ๋ฏ€๋กœ ์—๋Ÿฌ
if (x) { /* ... */ }
// String.isNotEmpty๋Š” ๋นˆ๋ฌธ์ž์—ด ์—ฌ๋ถ€๋ฅผ ๋ถˆ๋ฆฌ์–ธ์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ OK
if (x.isNotEmpty) { /* ... */ }

 

๋น„ํŠธ ์—ฐ์‚ฐ์ž(Bitwise)๋Š” ๋‘ ์–ธ์–ด๊ฐ€ ๊ฑฐ์˜ ๋™์ผํ•˜๋‹ค.

์˜๋ฏธ JavaScript ์—ฐ์‚ฐ์ž Dart ์—ฐ์‚ฐ์ž
AND & &
OR | |
XOR ^ ^
NOT ~expr ~expr
์™ผ์ชฝ ์‹œํ”„ํŠธ << <<
์˜ค๋ฅธ์ชฝ ์‹œํ”„ํŠธ >> >>
๋ถ€ํ˜ธ ์—†๋Š” ์˜ค๋ฅธ์ชฝ ์‹œํ”„ํŠธ >>> >>>

 

Dart๋„ ํ‘œํ˜„์‹์„ ํ‰๊ฐ€ํ•˜๊ธฐ ์œ„ํ•œ ์กฐ๊ฑด๋ถ€ ์—ฐ์‚ฐ์ž(์‚ผํ•ญ ์—ฐ์‚ฐ์ž)๋ฅผ ์ง€์›ํ•œ๋‹ค.

int num1 = 10;
int num2 = 15;
int max = (num1 > num2) ? num1 : num2;
print("The greatest number is $max"); // The greatest number is 15

 

Assignment operators

๊ฐ’ ํ• ๋‹น์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๋™์ผํ•˜๊ฒŒ = ์—ฐ์‚ฐ์ž๋ฅผ ์ด์šฉํ•œ๋‹ค. Dart๋„ ??= ๋„ ๋ณ‘ํ•ฉ ์—ฐ์‚ฐ์ž(null-aware variant)๋ฅผ ์ง€์›ํ•œ๋‹ค.

int? a;
int b = a ?? 5;
print(b); // 5

 

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์ฒ˜๋Ÿผ ๋ณ€์ˆ˜์— ๊ฐ’์„ ํ• ๋‹นํ•จ๊ณผ ๋™์‹œ์— ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ถ•์•ฝํ˜• ํ• ๋‹น ์—ฐ์‚ฐ์ž๋ฅผ ์ง€์›ํ•œ๋‹ค. ~/= ์ •์ˆ˜ ๋‚˜๋ˆ—์…ˆ ํ• ๋‹น์„ ์ œ์™ธํ•˜๊ณ  Dart, JavaScript์˜ ์ถ•์•ฝํ˜• ์—ฐ์‚ฐ์ž๋Š” ๋ชจ๋‘ ๋™์ผํ•˜๋‹ค.

์—ฐ์‚ฐ์ž ์„ค๋ช…
= ํ• ๋‹น
+= ๋ง์…ˆ ํ• ๋‹น
-= ๋บ„์…ˆ ํ• ๋‹น
*= ๊ณฑ์…ˆ ํ• ๋‹น
/= ๋‚˜๋ˆ—์…ˆ ํ• ๋‹น
~/= ์ •์ˆ˜ ๋‚˜๋ˆ—์…ˆ ํ• ๋‹น
%= ๋‚˜๋จธ์ง€(๋ชจ๋“ˆ๋กœ) ํ• ๋‹น
>>>= ๋ถ€ํ˜ธ ์—†๋Š” ์˜ค๋ฅธ์ชฝ ์‹œํ”„ํŠธ ํ• ๋‹น
^= ๋น„ํŠธ XOR ํ• ๋‹น
<<= ์™ผ์ชฝ ์‹œํ”„ํŠธ ํ• ๋‹น
>>= ์˜ค๋ฅธ์ชฝ ์‹œํ”„ํŠธ ํ• ๋‹น
&= ๋น„ํŠธ AND ํ• ๋‹น
|= ๋น„ํŠธ OR ํ• ๋‹น

 

int num = 5;
num *= 5;
print(num); // 25

 

Cascades (.. operator)

Dart์—์„  ๋™์ผํ•œ ๊ฐ์ฒด์— ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ์ด๋‚˜ ์†์„ฑ ์„ค์ •์„ ์—ฐ์†์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” Cascades ๊ตฌ๋ฌธ์„ ์ง€์›ํ•œ๋‹ค. ๊ฐ์ฒด๋ฅผ ๋ฐ˜๋ณตํ•ด์„œ ์ฐธ์กฐํ•˜์ง€ ์•Š๊ณ  ์›ํ•˜๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ์žฅ์ ์ด ์žˆ๋‹ค.

 

Cascades ๊ตฌ๋ฌธ์€ .. ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—๋Š” ์—†๋Š” ๊ตฌ๋ฌธ์ด๋‹ค. .. ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•ด์„œ ๋ฉ”์„œ๋“œ ์ฒด์ด๋‹์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€๋‹ค.

Map<String, dynamic> user = {'name': 'John', 'age': 30};

user
  ..['age'] = 31
  ..['city'] = 'Los Angeles';
  
print(user); // {name: John, age: 31, city: Los Angeles}

 

๊ฐ์ฒด๊ฐ€ null์ผ ์ˆ˜๋„ ์žˆ๋Š” ๊ฒฝ์šฐ ์ฒซ ๋ฒˆ์งธ Cascades ๊ตฌ๋ฌธ์— ?.. ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค

Map<String, dynamic>? user;

// user๊ฐ€ null์ผ ๊ฒฝ์šฐ ?.. ์—ฐ์‚ฐ์ž๋Š” null์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  Cascades ๊ตฌ๋ฌธ์€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค
user
  ?..['age'] = 31
  ..['city'] = 'Los Angeles';

print(user); // null

 

 

Collections


Lists

Dart์˜ List๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ฐฐ์—ด๊ณผ ๋™์ผํ•˜๊ฒŒ ๋Œ€๊ด„ํ˜ธ๋กœ ๋ฌถ๊ณ  ์‰ผํ‘œ๋กœ ๊ฐ’์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑํ•œ๋‹ค.

// ์ขŒ์ธก List<String> : ๋ฆฌ์ŠคํŠธ ๋ณ€์ˆ˜ ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •
// ์šฐ์ธก <String> : ๋ฆฌ์ŠคํŠธ ์š”์†Œ ํƒ€์ž…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •
// final : ๋ฆฌ์ŠคํŠธ์˜ ์š”์†Œ๋Š” ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฆฌ์ŠคํŠธ ์ž์ฒด๋Š” ๋‹ค๋ฅธ ๋ฆฌ์ŠคํŠธ๋กœ ์žฌํ• ๋‹น ๋ถˆ๊ฐ€
final List<String> list1 = <String>['one', 'two', 'three'];

// ๋ฆฌ์ŠคํŠธ ์š”์†Œ ํƒ€์ž…๋งŒ <String>์œผ๋กœ ์ง€์ •ํ•œ ์˜ˆ์‹œ
final list2 = <String>['one', 'two', 'three'];

// ํƒ€์ž…์„ ์ง€์ •ํ•˜์ง€ ์•Š์•˜์ง€๋งŒ List<String>์œผ๋กœ ์ถ”๋ก ๋จ
final list3 = ['one', 'two', 'three'];

 

์ธ๋ฑ์Šค ์—ฐ์‚ฐ์ž๋กœ ๊ฐ’์„ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค.

final fruits = <String>['apple', 'orange', 'pear'];
final fruit = fruits[1]; // orange
fruits[1] = 'pear';
print(fruits); // [apple, pear, pear]

 

add(), addAll() ๋ฉ”์„œ๋“œ๋กœ ๋ฆฌ์ŠคํŠธ์— ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

final fruits = <String>['apple', 'orange', 'pear'];
fruits.add('peach'); // 1๊ฐœ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ
fruits.addAll(['kiwi', 'mango']); // ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ

 

insert(), insertAll() ๋ฉ”์„œ๋“œ๋กœ ํŠน์ • ์ธ๋ฑ์Šค์— ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ์กด ์ธ๋ฑ์Šค์— ์žˆ๋˜ ์š”์†Œ๋Š” ๋’ค๋กœ ๋ฐ€๋ ค๋‚˜๊ฒŒ ๋œ๋‹ค.

final fruits = <String>['apple', 'orange', 'pear'];
// 1๋ฒˆ์งธ ์ธ๋ฑ์Šค์— peach ์‚ฝ์ž… -> [apple, peach, orange, pear]
fruits.insert(1, 'peach');
// 2๋ฒˆ์งธ ์ธ๋ฑ์Šค์— kiwi, mango ์‚ฝ์ž… -> [apple, peach, kiwi, mango, orange, pear]
fruits.insertAll(2, ['kiwi', 'mango']);

 

๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฆฌ์ŠคํŠธ์˜ ์š”์†Œ๋ฅผ ์ œ๊ฑฐ ํ•  ์ˆ˜ ์žˆ๋‹ค.

final fruits = <String>['apple', 'orange', 'pear'];
// 'pear' ๊ฐ’์„ ๊ฐ€์ง„ ์š”์†Œ ์ œ๊ฑฐ
fruits.remove('pear');
// ๋ฆฌ์ŠคํŠธ์˜ ๋งˆ์ง€๋ง‰ ์š”์†Œ ์ œ๊ฑฐ
fruits.removeLast();
// 1๋ฒˆ ์ธ๋ฑ์Šค์— ์žˆ๋Š” ์š”์†Œ ์ œ๊ฑฐ (2๋ฒˆ์งธ ์š”์†Œ ์ œ๊ฑฐ)
fruits.removeAt(1);
// 1(ํฌํ•จ)~3(๋ฏธํฌํ•จ) ์ธ๋ฑ์Šค์— ์žˆ๋Š” ์š”์†Œ ์ œ๊ฑฐ (1~2๋ฒˆ ์ธ๋ฑ์Šค์˜ ์š”์†Œ ์ œ๊ฑฐ)
fruits.removeRange(1, 3);
// 'p'๋ฅผ ํฌํ•จํ•˜๋Š” ๋ชจ๋“  ์š”์†Œ ์ œ๊ฑฐ (์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์š”์†Œ ์ œ๊ฑฐ)
fruits.removeWhere((fruit) => fruit.contains('p'));

 

length ์†์„ฑ์œผ๋กœ ์š”์†Œ ๊ฐœ์ˆ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

final fruits = <String>['a', 'b', 'c'];
print(fruits.length); // 3

 

isEmpty, isNotEmpty ๋ฉ”์„œ๋“œ๋กœ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๋น„์—ˆ๊ฑฐ๋‚˜ ๋น„์–ด์žˆ์ง€ ์•Š์€์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

var fruits = [];
print(fruits.isEmpty); // true
print(fruits.isNotEmpty); // false

 

List.filled() ๋ฉ”์„œ๋“œ๋กœ ๊ณ ์ •๋œ ๊ธธ์ด(length)์™€ ์ดˆ๊ธฐ๊ฐ’์„ ๊ฐ–๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋กœ ์ƒ์„ฑํ•œ ๋ฆฌ์ŠคํŠธ๋Š” ์š”์†Œ ์ถ”๊ฐ€/์ œ๊ฑฐ๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๊ณ  ์กฐํšŒ/์—…๋ฐ์ดํŠธ๋งŒ ํ•  ์ˆ˜ ์žˆ๋‹ค. 3๋ฒˆ์งธ ์ธ์ž growable๋ฅผ true๋กœ ์„ค์ •ํ•˜๋ฉด ๊ฐ€๋ณ€ ๊ธธ์ด ๋ฆฌ์ŠคํŠธ๋กœ ์ƒ์„ฑ๋ผ์„œ ์ถ”๊ฐ€/์ œ๊ฑฐ๋„ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค.

// ์ฒซ๋ฒˆ์งธ ์ธ์ž: ๋ฆฌ์ŠคํŠธ ๊ธธ์ด, 2๋ฒˆ์งธ ์ธ์ž: ์ฑ„์šธ ๊ฐ’, 3๋ฒˆ์งธ ์„ ํƒ์  ์ธ์ž: ๊ณ ์ •/๊ฐ€๋ณ€ ๊ธธ์ด ์—ฌ๋ถ€ 
final list1 = List.filled(3, 'a');
list1.removeLast(); // Cannot remove from a fixed-length list
list1[1] = 'b'; // OK

final list2 = List.filled(3, 'a', growable: true);
list2.removeLast();
print(list2); // ['a', 'a']

 

List.generate() ํ•จ์ˆ˜๋Š” ์ง€์ •๋œ ๊ธธ์ด์˜ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ , ์ƒ์„ฑ์ž ํ•จ์ˆ˜(2๋ฒˆ์งธ ์ธ์ž)๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์œผ๋กœ ์ฑ„์šด๋‹ค. ์ƒ์„ฑ๋œ ๋ฆฌ์ŠคํŠธ๋Š” growable ๊ฐ’์— ๋”ฐ๋ผ ๊ณ ์ •/๊ฐ€๋ณ€ ๊ธธ์ด์ผ ์ˆ˜ ์žˆ๋‹ค. JS์˜ Array.from() ๋ฉ”์„œ๋“œ์™€ ์—ฌ๋Ÿฌ๋ชจ๋กœ ์œ ์‚ฌํ•œ ์ ์ด ๋งŽ๋‹ค.

// ์ฒซ๋ฒˆ์งธ ์ธ์ž: ๋ฆฌ์ŠคํŠธ ๊ธธ์ด, 2๋ฒˆ์งธ ์ธ์ž: ์ƒ์„ฑ์ž ํ•จ์ˆ˜, 3๋ฒˆ์งธ ์„ ํƒ์  ์ธ์ž: ๊ณ ์ •/๊ฐ€๋ณ€ ๊ธธ์ด ์—ฌ๋ถ€
final list = List.generate(3, (i) => 'a-$i', growable: true);
print(list); // [a-0, a-1, a-2]

 

Sets

Dart๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ๋‹ค๋ฅด๊ฒŒ {} ์ค‘๊ด„ํ˜ธ๋ฅผ ์‚ฌ์šฉํ•œ ๋ฆฌํ„ฐ๋Ÿด ํ˜•์‹์œผ๋กœ ์ง‘ํ•ฉ์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ Set์€ ์‚ฝ์ž… ์ˆœ์„œ๋ฅผ ๊ธฐ์–ตํ•˜์ง€๋งŒ Dart๋Š” ์ˆœ์„œ๋ฅผ ๊ธฐ์–ตํ•˜์ง€ ์•Š๋Š” ์ ์ด ๋‹ค๋ฅด๋‹ค. ์š”์†Œ์˜ ์œ ์ผ์„ฑ์„ ๋ณด์žฅํ•˜๋Š” ์ ์€ ๋™์ผํ•˜๋‹ค.

final abc = {'a', 'b', 'c'};

 

{} ๋นˆ ์ค‘๊ด„ํ˜ธ ๋ฆฌํ„ฐ๋Ÿด์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Map์„ ์ƒ์„ฑํ•œ๋‹ค. Set(์ง‘ํ•ฉ)์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด ๋ช…์‹œ์ ์œผ๋กœ ํƒ€์ž…์„ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค. Set์˜ ์ œ๋„ค๋ฆญ ํƒ€์ž… ์ธ์ž๋Š” 1๊ฐœ๋‹ค. ํ—ท๊ฐˆ๋ฆด ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ฃผ์˜ํ•˜์ž.

final names = {};              // Map<dynamic, dynamic>
final names = <String, int>{}; // Map<String, int>
Map<String, int> name = {};    // Map<String, int>

final names = <String>{}; // Set<String>
Set<String> names = {};   // Set<String>

 

add(), addAll() ๋ฉ”์„œ๋“œ๋กœ ์ง‘ํ•ฉ์— ๊ฐ’์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

final fruits = {'apple', 'orange', 'pear'};
fruits.add('peach'); // 1๊ฐœ ์š”์†Œ๋งŒ ์ถ”๊ฐ€ํ•  ๋•Œ
fruits.addAll(['kiwi', 'mango']); // ์—ฌ๋Ÿฌ ์š”์†Œ๋ฅผ ์ถ”๊ฐ€ํ•  ๋•Œ
print(fruits); // {apple, orange, pear, peach, kiwi, mango}

 

๋‹ค์–‘ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ์ง‘ํ•ฉ์˜ ๊ฐ’์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.

final fruits = {'apple', 'orange', 'pear'};
// 'pear' ๊ฐ’์„ ๊ฐ€์ง„ ์š”์†Œ ์ œ๊ฑฐ (1๊ฐœ ์š”์†Œ ์ œ๊ฑฐ)
fruits.remove('pear');
// 'orange', 'apple' ์š”์†Œ ์ œ๊ฑฐ (์—ฌ๋Ÿฌ ์š”์†Œ ์ œ๊ฑฐ)
fruits.removeAll(['orange', 'apple']);
// 'p'๋ฅผ ํฌํ•จํ•˜๋Š” ๋ชจ๋“  ์š”์†Œ ์ œ๊ฑฐ (์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ์š”์†Œ ์ œ๊ฑฐ)
fruits.removeWhere((fruit) => fruit.contains('p'));

 

length ์†์„ฑ์œผ๋กœ ์ง‘ํ•ฉ์˜ ๊ฐœ์ˆ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

final fruits = {'apple', 'orange', 'pear'};
print(fruits.length); // 3

 

isEmpty, isNotEmpty ๋ฉ”์„œ๋“œ๋กœ ์ง‘ํ•ฉ์ด ๋น„์—ˆ๊ฑฐ๋‚˜ ๋น„์–ด์žˆ์ง€ ์•Š์€์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

final fruits = {'apple', 'orange', 'pear'};
print(fruits.isEmpty); // false
print(fruits.isNotEmpty); // true

 

Maps

Dart์˜ Map์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ Map ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋ชจ๋“  ์œ ํ˜•์„ ํ‚ค/๊ฐ’์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. Dart์˜ Map์€ ํ•ด์‹œ ํ…Œ์ด๋ธ”์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ชจ๋“  ํ‚ค๋Š” ํ•ด์‹œ ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ๋ฆฌํ„ฐ๋Ÿด์„ ์ด์šฉํ•ด์„œ Map์„ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ‚ค๊ฐ€ ๋ฌธ์ž์—ด์ด๋ผ๋ฉด ํ•ญ์ƒ ๋”ฐ์˜ดํ‘œ๋ฅผ ๋ถ™์—ฌ์•ผ ํ•œ๋‹ค.

final grades = { 'Alice': 'A', 'Bob': 'B', 'Charlie': 'C' };

 

์ธ๋ฑ์Šค ์—ฐ์‚ฐ์ž๋กœ ์›ํ•˜๋Š” ๊ฐ’์„ ์กฐํšŒ/์—…๋ฐ์ดํŠธ/์ˆ˜์ • ํ•  ์ˆ˜ ์žˆ๋‹ค. ์กฐํšŒํ•œ ํ‚ค๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ์—” null์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

final grades = { 'Alice': 'A' };

print(grades['Alice']); // A
print(grades['Bob']);   // null

grades['Bob'] = 'B';    // ์ถ”๊ฐ€
grades['Bob'] = 'B+';   // ์—…๋ฐ์ดํŠธ

 

containsKey() ๋ฉ”์„œ๋“œ๋กœ ํ‚ค ํฌํ•จ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

final grades = { 'Alice': 'A' };
print(grades.containsKey('Alice')); // true

 

addAll() ๋ฉ”์„œ๋“œ๋กœ ๋‹ค๋ฅธ Map์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ addEntries() ๋ฉ”์„œ๋“œ๋กœ MapEntry ๊ฐ์ฒด(์ดํ„ฐ๋Ÿฌ๋ธ”)๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. MapEntry๋Š” Map์˜ ๊ฐœ๋ณ„ ํ‚ค/๊ฐ’ ์Œ์„ ๋‚˜ํƒ€๋‚ด๋Š” ๊ฐ์ฒด๋‹ค.

final grades = { 'Alice': 'A' };

grades.addAll({ 'Bob': 'B' });
print(grades); // {Alice: A, Bob: B}

final charlieGrade = MapEntry('Charlie', 'C'); // MapEntry(Charlie: C)
grades.addEntries([charlieGrade]);
print(grades); // {Alice: A, Bob: B, Charlie: C}

 

remove()๋กœ ํŠน์ • ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜, removeWhere()๋กœ ์กฐ๊ฑด์— ๋ถ€ํ•ฉํ•˜๋Š” ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋‹ค.

final grades = {'Alice': 'A', 'Bob': 'B', 'Charlie': 'C'};

grades.remove('Alice');
grades.removeWhere((key, value) => value == 'B');
print(grades); // {Charlie: C}

 

length ์†์„ฑ์œผ๋กœ ํ•ญ๋ชฉ์˜ ๊ฐœ์ˆ˜๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

final grades = {'Alice': 'A', 'Bob': 'B', 'Charlie': 'C'};
print(grades.length); // 3

 

isEmpty, isNotEmpty ๋ฉ”์„œ๋“œ๋กœ Map์ด ๋น„์—ˆ๊ฑฐ๋‚˜ ๋น„์–ด์žˆ์ง€ ์•Š์€์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

final grades = {'Alice': 'A', 'Bob': 'B', 'Charlie': 'C'};
print(grades.isEmpty); // false
print(grades.isNotEmpty); // true

 

Unmodifiable

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ถˆ๋ณ€์„ฑ์„ ์ง€์›ํ•˜์ง€ ์•Š์ง€๋งŒ Dart๋Š” ๋ถˆ๋ณ€์„ฑ์œผ๋กœ ๋งŒ๋“œ๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค. ์ˆ˜์ •ํ•˜๋ฉด ์•ˆ ๋˜๋Š” ์ปดํŒŒ์ผ ์ƒ์ˆ˜ ์ปฌ๋ ‰์…˜์€ const ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค(์ถ”๊ฐ€/์ œ๊ฑฐ ๋ถˆ๊ฐ€).

const fruits = <String>{'apple', 'orange', 'pear'};

 

final ํ‚ค์›Œ๋“œ๋กœ ์ •์˜ํ•œ ์ง‘ํ•ฉ์€ ์žฌํ• ๋‹น ํ•  ์ˆ˜ ์—†์ง€๋งŒ ์š”์†Œ์˜ ์ถ”๊ฐ€/์ œ๊ฑฐ๋Š” ํ—ˆ์šฉํ•œ๋‹ค.

final fruits = <String>{'apple', 'orange', 'pear'};
fruits.remove('apple'); // OK
fruits.add('banana'); // OK

 

unmodifiable ์ƒ์„ฑ์ž๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋Ÿฐํƒ€์ž„ ๋ถˆ๋ณ€์„ฑ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ๋‹ค(์ถ”๊ฐ€/์ œ๊ฑฐ ๋ถˆ๊ฐ€).

final _set = Set<String>.unmodifiable(['a', 'b', 'c']);
final _list = List<String>.unmodifiable(['a', 'b', 'c']);
final _map = Map<String, String>.unmodifiable({'foo': 'bar'});

 

Spread operator

Dart๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์ฒ˜๋Ÿผ ... ์ „๊ฐœ ์—ฐ์‚ฐ์ž๋ฅผ ์ง€์›ํ•œ๋‹ค.

final list1 = [1, 2, 3];
final list2 = [0, ...list1];
print(list2); // [0, 1, 2, 3]

 

์ปฌ๋ ‰์…˜์ด null ์ผ ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์—” ...? ๋„ ์ธ์‹ ์ „๊ฐœ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๋ฅผ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

final list1 = null;
final list2 = [0, ...?list1];
print(list2); // [0]

 

์ „๊ฐœ ์—ฐ์‚ฐ์ž๋Š” List, Set, Map ๋“ฑ ์ดํ„ฐ๋Ÿฌ๋ธ”์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. Dart์˜ ๋ฌธ์ž์—ด์€ Iterable ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ตฌํ˜„๋˜์–ด ์žˆ์ง€ ์•Š์ง€๋งŒ split() ๋ฉ”์„œ๋“œ ๋“ฑ์„ ํ™œ์šฉํ•ด์„œ ์ดํ„ฐ๋Ÿฌ๋ธ”์ฒ˜๋Ÿผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค. ์ฐธ๊ณ ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ฌธ์ž์—ด์€ Iterable ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๊ตฌํ˜„๋˜์–ด ์žˆ๋Š” ์ดํ„ฐ๋Ÿฌ๋ธ”์ด์–ด์„œ ์ „๊ฐœ ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

// Map์—์„œ ์ „๊ฐœ ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ ์˜ˆ์‹œ
final map1 = { 'a': 1, 'b': 2 };
final map2 = { ...map1, 'c': 3 };
print(map2); // {a: 1, b: 2, c: 3}

// Set์—์„œ ์ „๊ฐœ ์—ฐ์‚ฐ์ž ์‚ฌ์šฉ ์˜ˆ์‹œ
final set1 = {1, 2, 3};
final set2 = {0, ...set1};
print(set2); // {0, 1, 2, 3}

 

Collection if/for

Dart๋Š” ์ปฌ๋ ‰์…˜(List, Set ๋“ฑ) ๋‚ด๋ถ€์—์„œ if-else, for ๋ฌธ์„ ์‚ฌ์šฉํ•˜์—ฌ ์š”์†Œ๋ฅผ ๋™์ ์œผ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

bool isLoggedIn = true;

final userMenu = [
  'Profile',
  'Settings',
  if (isLoggedIn) 'Logout' else 'Login',
  if (isLoggedIn) 'Edit'
];

print(userMenu); // [Profile, Settings, Logout, Edit]

 

์ปฌ๋ ‰์…˜ ์•ˆ์—์„œ for ๋ฌธ์„ ํ™œ์šฉํ•˜๋ฉด ๋‹ค๋ฅธ ์ปฌ๋ ‰์…˜์„ ๋งคํ•‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

final keys = ['one', 'two', 'three'];
final values = [1, 2, 3];

final map = {
  'zero': 0,
  for (var i = 0; i < keys.length; i++) keys[i]: values[i]
};

print(map); // {zero: 0, one: 1, two: 2, three: 3}

 

for, if ๋ฌธ์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

final numbers = List.generate(5, (i) => i + 1); // [1, 2, 3, 4, 5]
final doubledEvenNumbers = [
  for (var number in numbers)
    if (number % 2 == 0) number * 2 else number
];
 
print(doubledEvenNumbers); // [1, 4, 3, 8, 5]

 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”
๋ฐ˜์‘ํ˜•