Contents

[Dart] Dart ๋ฌธ๋ฒ• ์ •๋ฆฌ

๐Ÿ˜Š
Dart ๊ธฐ๋ณธ ๋ฌธ๋ฒ•์˜ ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋ถ€๋ถ„๊ณผ ๋ชฐ๋ž๋˜ ๋ถ€๋ถ„ ์ •๋ฆฌ! ๐Ÿธ๐Ÿธ

Final ๊ณผ const

final๊ณผ const ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ ์–ธํ•˜๋ฉด ํ• ๋‹นํ•œ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋‹ค. ๋‘˜๋‹ค ์ƒ์ˆ˜๋ฅผ ์„ ์–ธํ•  ๋•Œ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์ฐจ์ด์ ์€ const๋Š” complie-time์— ์ƒ์ˆ˜๋ฅผ ์„ค์ •ํ•˜๋ฉฐ final์€ runtime์‹œ์— ๊ฒฐ์ •๋˜๋Š” ๊ฐ’๋„ ์ƒ์ˆ˜๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
4
// error 
const DateTime now1 = DateTime.now(); // error! const๋Š” runtime์‹œ์— ๊ฐ’์ด ๊ฒฐ์ •๋˜๋Š” ๊ฐ’์€ ์„ค์ •ํ•  ์ˆ˜ ์—†๋‹ค.
 
final DateTime now2 = DateTime.now(); // final์€ runtime์‹œ์— ๊ฒฐ์ •๋˜๋Š” ๊ฐ’๋„ ์„ค์ • ๊ฐ€๋Šฅํ•˜๋‹ค.
Note
Instance variables๋Š” final ์ผ ์ˆ˜ ์žˆ์ง€๋งŒ const๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Œ

const๋Š” complie-time์— ์‚ฌ์šฉํ•  ์ƒ์ˆ˜๋ฅผ ์„ ์–ธํ•œ๋‹ค. ๋งŒ์•ฝ ํด๋ž˜์Šค ๋ ˆ๋ฒจ์—์„œ const๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” static const๋ฅผ ์‚ฌ์šฉ๋ฉด ๋œ๋‹ค. const๋กœ ์„ ์–ธํ•œ ์ƒ์ˆ˜์— ๋Œ€ํ•œ ์‚ฐ์ˆ ์—ฐ์‚ฐ ๋“ฑ์˜ ๊ฒฐ๊ณผ ๋˜ํ•œ const ์ƒ์ˆ˜์—ฌ์•ผ ํ•œ๋‹ค.

1
2
const bar = 1000000; // Unit of pressure (dynes/cm2)
const double atm = 1.01325 * bar; // Standard atmosphere

const ํ‚ค์›Œ๋“œ๋Š” ์ƒ์ˆ˜ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฒƒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ƒ์ˆ˜ ๊ฐ’์„ ์ƒ์„ฑํ•˜๋Š” ์ƒ์„ฑ์ž ์„ ์–ธ์—๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
3
var foo = const [];
final bar = const [];
const baz = []; // Equivalent to `const []`

final ํ‚ค์›Œ๋“œ์˜ ๊ฒฝ์šฐ ๊ฐœ์ฒด๋Š” ์ˆ˜์ •ํ•  ์ˆ˜ ์—†์ง€๋งŒ ํ•ด๋‹น ํ•„๋“œ๋Š” ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ const์˜ ๊ฒฝ์šฐ ๊ฐœ์ฒด์™€ ํ•„๋“œ๋ฅผ ๋ณ€๊ฒฝ ํ•  ์ˆ˜ ์—†๋‹ค.

1
2
3
4
5
6
final List<String> cats = ["๊ฐœ๋ƒฅ์ด", "๋ฌผ์†์„ฑ๋ƒฅ์ด"];
cats.add("๋ƒฅ๋ƒฅํŽ€์น˜๋ƒฅ์ด");
print(cats);
  
const List<String> dogs = ["๊ฐ•ํ˜•์šฑ๋„ ๋ชป ๋ง๋ฆฌ๋Š” ๊ฐœ", "๊ฐ•ํ˜•์šฑ๋„ ๋ฌด๋Š” ๊ฐœ"];
dogs[0] = "์šฐ๋ฆฌ์ง‘๊ฐœ"; // error!

Typedefs

typedef๋Š” ํƒ€์ž…์— ๋Œ€ํ•œ ๋ณ„์นญ์„ ๋‚˜ํƒ€๋‚ด๋Š” ํ‚ค์›Œ๋“œ์ด๋ฉฐ ํƒ€์ž…์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์•„๋ž˜๋Š” IntList๋ผ๋Š” ํƒ€์ž… ๋ณ„์นญ์„ ์„ ์–ธํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ์ด๋‹ค.

1
2
typedef IntList = List<int>;
IntList il = [1, 2, 3];

ํƒ€์ž… ๋ณ„์นญ์€ ํƒ€์ž… ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค.

1
2
typedef ListMapper<X> = Map<X, List<X>>;
ListMapper<String> m = {}; // Map<String, List<String>>

ํƒ€์ž… ๋ณ„์นญ ๋Œ€์‹  inline function types์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•œ๋‹ค๊ณ  ํ•œ๋‹ค.

1
2
3
4
5
6
7
typedef Compare<T> = int Function(T a, T b);

int sort(int a, int b) => a - b;

void main() {
  assert(sort is Compare<int>); // True!
}

Asynchronous programming

Future

Future๋Š” ๋น„๋™๊ธฐ ์ž‘์—…์˜ ๊ฒฐ๊ณผ๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ ์™„๋ฃŒ๋˜์ง€ ์•Š์Œ ๋˜๋Š” ์™„๋ฃŒ๋จ์˜ ๋‘ ๊ฐ€์ง€ ์ƒํƒœ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

  • Future๋Š” ํƒ€์ž…ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๊ฐ–๋Š” ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  • Future์—์„œ ๋ฆฌํ„ด๊ฐ’์ด ์—†์„ ๊ฒฝ์šฐ ํƒ€์ž…์€ Future<void> ์ด๋‹ค.
  • future์˜ ์ƒํƒœ ๊ฐ’์€ uncompleted ๋˜๋Š” completed ๋‘ ๊ฐ€์ง€ ์ค‘ ํ•˜๋‚˜ ์ด๋‹ค.
  • future ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ์ˆ˜ํ–‰ํ•  ์ž‘์—…์„ ๋Œ€๊ธฐ์—ด์— ๋„ฃ๊ณ  uncompleted ๋œ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • future ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด future ํ˜น์€ ์˜ค๋ฅ˜์™€ ํ•จ๊ป˜ ์™„๋ฃŒ๋œ๋‹ค.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
void main() {
  addNumbers(1, 1);
  addNumbers(2, 2);
}

void addNumbers(int number1, int number2) {
  print('๊ณ„์‚ฐ์‹œ์ž‘ : $number1 + $number2');

  // ์„œ๋ฒ„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜
  Future.delayed(Duration(seconds: 2), (){
    print('๊ณ„์‚ฐ์™„๋ฃŒ : $number1 + $number2 = ${number1 + number2}');
  });
  
  print('ํ•จ์ˆ˜ ์™„๋ฃŒ');  
}

Console
๊ณ„์‚ฐ์‹œ์ž‘ : 1 + 1
ํ•จ์ˆ˜ ์™„๋ฃŒ
๊ณ„์‚ฐ์‹œ์ž‘ : 2 + 2
ํ•จ์ˆ˜ ์™„๋ฃŒ
๊ณ„์‚ฐ์™„๋ฃŒ : 1 + 1 = 2
๊ณ„์‚ฐ์™„๋ฃŒ : 2 + 2 = 4

Working with futures: async and await

async ํ•จ์ˆ˜๋Š” ์ฒซ ๋ฒˆ์งธ await ํ‚ค์›Œ๋“œ๊นŒ์ง€ ๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋œ๋‹ค. async ํ•จ์ˆ˜ ๋‚ด์— ์ฒซ๋ฒˆ์งธ await ํ‚ค์›Œ๋“œ ์•ž์˜ ๋ชจ๋“  ์ฝ”๋“œ๋Š” ์ฆ‰์‹œ ์‹คํ–‰๋œ๋‹ค.

  • async : ํ•จ์ˆ˜ ์•ž์— async ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • awiat : await ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋™๊ธฐ ํ•จ์ˆ˜์˜ ์™„๋ฃŒ๋œ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. await ํ‚ค์›Œ๋“œ๋Š” async ํ•จ์ˆ˜ ๋‚ด์—์„œ๋งŒ ๋™์ž‘ํ•œ๋‹ค.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
void main() {
  addNumbers(1, 1);
  addNumbers(2, 2);
}

Future<void> addNumbers(int number1, int number2) async {
  print('๊ณ„์‚ฐ์‹œ์ž‘ : $number1 + $number2');

  // ์„œ๋ฒ„ ์‹œ๋ฎฌ๋ ˆ์ด์…˜
  await Future.delayed(Duration(seconds: 2), (){
    print('๊ณ„์‚ฐ์™„๋ฃŒ : $number1 + $number2 = ${number1 + number2}');
  });
  
  print('ํ•จ์ˆ˜ ์™„๋ฃŒ');  
}

Console
๊ณ„์‚ฐ์‹œ์ž‘ : 1 + 1
๊ณ„์‚ฐ์‹œ์ž‘ : 2 + 2
๊ณ„์‚ฐ์™„๋ฃŒ : 1 + 1 = 2
ํ•จ์ˆ˜ ์™„๋ฃŒ
๊ณ„์‚ฐ์™„๋ฃŒ : 2 + 2 = 4
ํ•จ์ˆ˜ ์™„๋ฃŒ

Stream

Dart์—์„œ๋Š” ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์œ„ํ•œ Future์™€ Stream ๋‘ ๊ฐ€์ง€ ํด๋ž˜์Šค๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

  • stream์€ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์—ฐ์†์ ์ธ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
  • Stream API์—์„œ await for ๋˜๋Š” listen()์„ ์‚ฌ์šฉํ•˜์—ฌ ์ŠคํŠธ๋ฆผ์„ ์ฒ˜๋ฆฌ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์ŠคํŠธ๋ฆผ์—๋Š” single subscription ๊ณผ broadcast ๋‘๊ฐ€์ง€ ์ข…๋ฅ˜๋ฅผ ์ œ๊ณตํ•œ๋‹ค.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import 'dart:async';

void main() {
  final controller = StreamController();
  
  final stream = controller.stream.asBroadcastStream();
  
  // ์ง์ˆ˜๋งŒ ์ถœ๋ ฅํ•˜๊ธฐ
  final streamListener1 = stream.where((val) => val % 2 == 0).listen((val) {
    print('Listener 1 : $val');
  });
  
  // ํ™€์ˆ˜๋งŒ ์ถœ๋ ฅํ•˜๊ธฐ
  final streamListener2 = stream.where((val) => val % 2 == 1).listen((val){
    print('Listener 2 : $val');
  });
  
  controller.sink.add(1);
  controller.sink.add(2);
  controller.sink.add(3);
  controller.sink.add(4);
  controller.sink.add(5);
}

Console
Listener 2 : 1
Listener 1 : 2
Listener 2 : 3
Listener 1 : 4
Listener 2 : 5

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import 'dart:async';

void main() {
  calculate(2).listen((val) {
    print('calculate(2) : $val');
  });
  calculate(4).listen((val) {
    print('calculate(4) : $val');
  });
}

Stream<int> calculate(int number) async* {
  for(int i = 0; i < 5; i++) {
    yield i * number;   
    await Future.delayed(Duration(seconds: 1));
  }
}

Console
calculate(2) : 0
calculate(4) : 0
calculate(2) : 2
calculate(4) : 4
calculate(2) : 4
calculate(4) : 8
calculate(2) : 6
calculate(4) : 12
calculate(2) : 8
calculate(4) : 16

์ฐธ๊ณ