[Flutter] Dart 문법 정리 🎯 (type / operator / function / null safety)

dosilvΒ·2021λ…„ 7μ›” 15일
13
post-thumbnail

본격적으둜 ν”ŒλŸ¬ν„°μ— λ“€μ–΄κ°€κΈ° 전에! λ‚΄κ°€ 보렀고 정리해 λ†“λŠ” λ‹€νŠΈ 문법 πŸ—’


🎯 Dart μ–Έμ–΄μ˜ νŠΉμ§•

  • statically typed language (but dynamic type도 지원함!)
  • κ°•λ ₯ν•œ 객체지ν–₯ μ–Έμ–΄λ‘œμ„œ λͺ¨λ“  것이 객체! (심지어 μˆ«μžλ„ 객체)
  • 단일상속(single inheritance)κ³Ό mixin을 지원함

🎯 Type

πŸ•Ή λ‹€νŠΈμ˜ νƒ€μž… μ’…λ₯˜

🚦 κΈ°λ³Έ μžλ£Œν˜•

  • int: μ •μˆ˜ν˜•
  • double: μ‹€μˆ˜ν˜•
  • num: int, double을 ν¬ν•¨ν•˜λŠ” νƒ€μž…
  • bool: true, false
  • String: λ¬Έμžμ—΄ (보톡 μž‘μ€ λ”°μ˜΄ν‘œλ‘œ ν‘œμ‹œ)

🚦 집합 μžλ£Œν˜•

  • List: 쀑볡을 ν—ˆμš©ν•˜λ©° μˆœμ„œκ°€ μžˆλŠ” 집합
  • Set: 쀑볡을 ν—ˆμš©ν•˜μ§€ μ•Šκ³  μˆœμ„œκ°€ μ—†λŠ” 집합
  • Map: key-value 쌍으둜 κ΅¬μ„±λœ 집합 (JS의 Object, Python의 dictionary와 λΉ„μŠ·..!)


πŸ•Ή νƒ€μž… μ„ μ–Έ

🚦 κΈ°λ³Έ μžλ£Œν˜•

λ³€μˆ˜λͺ…: νƒ€μž…μœΌλ‘œ λ‚˜νƒ€λ‚΄λŠ” νƒ€μž…μŠ€ν¬λ¦½νŠΈμ™€ 달리, λ‹€νŠΈμ—μ„œλŠ” ν˜•μ‹μ„ λ³€μˆ˜ μ•žμ— ν‘œμ‹œν•œλ‹€.

String name;
int age;

🚦 집합 μžλ£Œν˜•

집합 μžλ£Œν˜•μ˜ 경우 νƒ€μž…<μš”μ†Œμ˜ νƒ€μž…> ν˜•νƒœλ‘œ λ‚˜νƒ€λƒ„!

List<int> numbers = [0, 1, 2];

Map<String, int> scores = {
  'eng': 100,
  'math': 90,
  'science': 80
}

🚦 ν•¨μˆ˜

ν•¨μˆ˜μ˜ λ°˜ν™˜ νƒ€μž… μ—­μ‹œ ν•¨μˆ˜λͺ… μ•žμ— λΆ™μ—¬ μ€€λ‹€.

void main() {
  print('Hello!');
}

String greeting() {
  return 'Hello!';
}


πŸ•Ή var/dynamic

🚦 var: νƒ€μž… μΆ”λ‘ 

var ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜λ©΄ νƒ€μž…μ„ μ„ μ–Έν•˜μ§€ μ•Šμ•„λ„ λ³€μˆ˜μ— ν• λ‹Ήλœ μ΄ˆκΈ°κ°’μ— 따라 νƒ€μž…μ΄ μžλ™μœΌλ‘œ μΆ”λ‘ λœλ‹€. 이후 ν•΄λ‹Ή λ³€μˆ˜λŠ” νƒ€μž… λ³€κ²½ ❌ ❌

void main() {
  var age = 5;		//int type
  var name = dana;	//String type
  var human = true;	//bool type
  age = 20;		//문제 μ—†μŒ
  age = 'hi';		//Error: A value of type 'String' can't be assigned to a variable of type 'int'.
}

🚦 dynamic: 동적 νƒ€μž… 지정

λ³€μˆ˜ μ„ μ–Έ μ‹œ dynamic을 λΆ™μ—¬μ£Όλ©΄ μ»΄νŒŒμΌλŸ¬κ°€ ν•΄λ‹Ή λ³€μˆ˜μ— λͺ¨λ“  ν˜•μ‹μ„ ν—ˆμš©ν•œλ‹€. 이후 νƒ€μž…μ„ 변경해도 μ—λŸ¬κ°€ λ‚˜μ§€ μ•ŠμŒ!

void main() {
  dynamic something = 9;
  something = 'apple';
  print(something);	//apple
}

πŸ“Œ final, const, static

  • λ³€μˆ˜μ˜ ν˜•μ‹μ„ ν™•μž₯ν•˜λŠ” ν‚€μ›Œλ“œ
  • final, const λͺ¨λ‘ λΆˆλ³€ν•˜λŠ” μƒμˆ˜λ₯Ό μ˜λ―Έν•˜μ§€λ§Œ μ•½κ°„μ˜ 차이가 있음
    • constλŠ” μ•±μ˜ life cycleμ—μ„œ μ ˆλŒ€ λ³€ν•˜μ§€ μ•ŠμŒμ„ μ˜λ―Έν•˜κΈ° λ•Œλ¬Έμ— λΆˆλ³€ λ³€μˆ˜μ˜ μ•žμ— constλ₯Ό λΆ™μ—¬ μ£Όλ©΄ ν”ŒλŸ¬ν„°κ°€ κ·Έ 뢀뢄을 rebuildν•˜μ§€ μ•Šκ³ , λ”°λΌμ„œ μ•±μ˜ 속도가 빨라진닀 (μ„±λŠ₯ κ°œμ„ )
    • constλŠ” compile-time constant둜 μ•± λΉŒλ“œμ‹œ 값이 μ •ν•΄μ§€λŠ” 반면, final은 run-time constantλ‘œμ„œ μ•± λΉŒλ“œμ‹œμ—λŠ” 값이 정해지지 μ•Šμ§€λ§Œ μ•± μ‹€ν–‰μ‹œ 값이 정해진닀 (e.g. DateTime.now, Device size λ“±)
  • static은 클래슀 레벨의 λ³€μˆ˜λ₯Ό μ˜λ―Έν•˜λ©°, 클래슀의 각 μΈμŠ€ν„΄μŠ€λŠ” ν•˜λ‚˜μ˜ static 값을 κ³΅μœ ν•œλ‹€


🎯 Operator

πŸ•Ή κΈ°λ³Έ μ—°μ‚°μž

기본적인 μ—°μ‚°μžλŠ” JS와 크게 λ‹€λ₯΄μ§€ μ•Šλ‹€. μƒμ†Œν•˜κ±°λ‚˜ νŠΉμ΄ν•œ κ²ƒλ§Œ 정리해 λ΄„!

🚦 ~/

μ •μˆ˜ λ‚˜λˆ—μ…ˆ 기호

void main() {
  print(55~/2);		//27
}

🚦 as

κ°•μ œ ν˜•λ³€ν™˜ ν‚€μ›Œλ“œλ‘œμ„œ λΆ€λͺ¨ νƒ€μž…μ˜ 객체λ₯Ό μžμ‹ νƒ€μž…μ˜ 객체둜 ν˜•λ³€ν™˜(=λ‹€μš΄μΊμŠ€νŒ…)ν•  λ•Œ μ‚¬μš©


🚦 is / is!

객체의 νƒ€μž…μ„ 확인해 true/false λ°˜ν™˜

void main() {
  var age = 0;
  print(age is int);	//true
  print(age is num);	//true
  print(age is! num);	//false
}


πŸ•Ή null-aware μ—°μ‚°μž

객체가 null일 경우λ₯Ό μΈμ§€ν•˜μ—¬ μ—λŸ¬ λ°œμƒμ„ 막고 λ‹€λ₯Έ 값을 ν• λ‹Ήμ‹œν‚€λŠ” μ—°μ‚°μž!

🚦 A?.B

optional chaining이라고 κ³΅λΆ€ν–ˆλ˜ 것
Aκ°€ null이 μ•„λ‹ˆλ©΄ A 객체의 B 속성을 μ‚¬μš©ν•˜κ³ , null이면 κ·Έλƒ₯ null을 λ°˜ν™˜

void main() {
  String? name;
  print(name.length);	//Error: Property 'length' cannot be accessed on 'String?' because it is potentially null.
  print(name?.length);	//?.둜 μ²˜λ¦¬ν•΄ μ£Όλ©΄ μ—λŸ¬κ°€ λ‚˜μ§€ μ•ŠμŒ
}

🚦 A ?? B

JS의 || μ—°μ‚°μžμ™€ κ°™μŒ! Aκ°€ null이면 Bλ₯Ό λ°˜ν™˜

void main() {
  int age = 16;
  int myAge = age ?? 20;
  print(myAge);		//ageκ°€ null이 μ•„λ‹ˆλ―€λ‘œ 16
}

🚦 A ??= B

μœ„μ™€ λ°˜λŒ€λ‘œ Bκ°€ null이면 백업값을 ν• λ‹Ήν•˜κ³ , μ•„λ‹ˆλ©΄ Bλ₯Ό λ°˜ν™˜

void main() {
  int age;
  int myAge = 24;
  myAge ??= age;
  print(myAge);		//ageκ°€ nullμ΄λ―€λ‘œ 24
}


🎯 Function

πŸ•Ή ν•¨μˆ˜μ˜ ꡬ쑰

🚦 기본 ꡬ쑰

리턴값 νƒ€μž… ν•¨μˆ˜λͺ… (νŒŒλΌλ―Έν„° νƒ€μž… νŒŒλΌλ―Έν„°) {}

String sayHi(String name) {
  return 'Hi $name!';
}

🚦 ν™”μ‚΄ν‘œ ν•¨μˆ˜

JS와 달리 ν™”μ‚΄ν‘œ ν•¨μˆ˜λ„ 이름을 가지며, {return 리턴값}을 => λ¦¬ν„΄κ°’μœΌλ‘œ μΆ•μ•½ν•  수 μžˆλ‹€.

String sayHi(String name) => 'Hi $name!';

πŸ“Œ main ν•¨μˆ˜

void main() {
  //μ½”λ“œ
}
  • dart ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λ©΄ 처음 μ‹€ν–‰λ˜λŠ” μ½”λ“œ (μ§„μž…νŒŒμΌμ— λ°˜λ“œμ‹œ μ •μ˜λ˜μ–΄ μžˆμ–΄μ•Ό 함!)
  • void: 리턴값이 μ—†μŒμ„ 의미


πŸ•Ή parameter

🚦 named parameter

νŒŒλΌλ―Έν„°λ₯Ό μ€‘κ΄„ν˜Έ({})둜 감싸면 named parameterκ°€ λ˜μ–΄ μ΄λ¦„μœΌλ‘œ νŒŒλΌλ―Έν„°λ₯Ό 전달할 수 μžˆλ‹€. 선택사항이기 λ•Œλ¬Έμ— 이름 없이 ν˜ΈμΆœν•  μˆ˜λ„ 있음!

void main() {
  void introduce({required String name, required int age}) {
    print('I am $name. $age yaers old!');
  }
  
  introduce(name: 'Sam', age: 5);	//I am Sam. 5 years old!
}

🚦 optional parameter

νŒŒλΌλ―Έν„°λ₯Ό λŒ€κ΄„ν˜Έ([])둜 감싸면 μ„ νƒν˜• 인자λ₯Ό μ„€μ •ν•  수 μžˆλ‹€.

void main() {
  void introduce(String name, int age, [String? food]) {
    print('I am $name. $age yaers old!');
    if (food is String) {
      print('I like $food!');
    }
  }

  introduce('Tom', 7);	//I am Tom. 7 yaers old!
  introduce('Sam', 5, 'ice cream');	//I am Sam. 5 yaers old! I like ice cream!
}

🚦 default parameter

= μ—°μ‚°μžλ₯Ό μ΄μš©ν•΄ νŒŒλΌλ―Έν„°μ˜ 기본값을 μ •μ˜ν•  수 μžˆλ‹€.

void main() {
  void introduce(String name, int age, [String food = 'chocolate']) {
    print('I am $name. $age yaers old! I like $food!');
  }

  introduce('Tom', 7); //I am Tom. 7 yaers old! I like chocolate!
}


🎯 Null Safety

ν”ŒλŸ¬ν„° 2.0, λ‹€νŠΈ 2.12μ—μ„œ μ—…λ°μ΄νŠΈλœ 문법!
κΈ°λ³Έκ°’ μ΄ˆκΈ°ν™”(initialize) 없이 μ„ μ–Έν•˜λŠ” λ³€μˆ˜λŠ”, null 값에 λŒ€ν•œ μ•ˆμ •μ„±μ„ 보μž₯ν•˜κΈ° μœ„ν•΄ νƒ€μž…μ„ nullableκ³Ό non-nullable둜 ꡬ뢄해 μ€˜μ•Ό ν•œλ‹€.

πŸ•Ή nullable

일반 νƒ€μž… 뒀에 λ¬ΌμŒν‘œ(?)λ₯Ό λΆ™μ—¬ μ£Όλ©΄ ν•΄λ‹Ή λ³€μˆ˜λŠ” ν•΄λ‹Ή νƒ€μž… λ˜λŠ” null이 될 수 μžˆμŒμ„ λ‚˜νƒ€λ‚Έλ‹€. μ΄ˆκΈ°ν™” 없이 μ‚¬μš©ν•˜λ©΄ null κ°’μœΌλ‘œ ν• λ‹Ήλœλ‹€.

void main() {
  String? name;
  int? age;
  bool? student;
  
  print(name)	//null
}

πŸ•Ή non-nullable

λ¬ΌμŒν‘œ 없이 일반 νƒ€μž…μœΌλ‘œ μ‚¬μš©ν•˜λ©΄ μžλ™μ μœΌλ‘œ null이 될 수 μ—†λŠ” κ°’μœΌλ‘œ μΈμ‹λœλ‹€. μ‚¬μš© 전에 λ°˜λ“œμ‹œ μ΄ˆκΈ°κ°’μ„ ν• λ‹Ήν•΄ μ€˜μ•Ό 함! μ•ˆ 그러면 μ•„λž˜μ²˜λŸΌ 였λ₯˜κ°€ λœ¬λ‹€.

void main() {
  String name;
  int age;
  bool student;
  
  print(name);  //The non-nullable local variable 'name' must be assigned before it can be used.
}

πŸ•Ή required, late

λ§ˆμ°¬κ°€μ§€λ‘œ null safetyλ₯Ό μœ„ν•΄ μΆ”κ°€λœ ν‚€μ›Œλ“œλ“€!

  • required
    ν•¨μˆ˜μ—μ„œ λ„€μž„λ“œ νŒŒλΌλ―Έν„°λ‚˜ μ˜΅μ…”λ„ νŒŒλΌλ―Έν„°λ₯Ό μ„€μ •ν•  λ•Œ non-nullable둜 μ§€μ •ν•˜κΈ° μœ„ν•΄ νƒ€μž… μ•žμ— λΆ™μ—¬μ€€λ‹€.
void greeting({required String name}) {
  print('Hello $name!');
}
  • late
    ν΄λž˜μŠ€μ— non-nullable ν”„λ‘œνΌν‹°κ°€ ν•„μš”ν•˜μ§€λ§Œ λ””ν΄νŠΈκ°’μ΄λ‚˜ μ΄ˆκΈ°ν™”λ₯Ό μ‹œν‚€μ§€ μ•Šμ„ 경우 λ‚˜μ€‘μ— 값을 ν• λ‹Ήν•œλ‹€λŠ” 의미둜 λΆ™μ—¬μ€€λ‹€.
class Cat {
  late String name;
  late int age;
}



객체지ν–₯ 뢀뢄은 λ‚˜μ€‘μ— λ”°λ‘œ 써야할 λ“―~~~😡😡😡

🧚🏻 Reference

[Dart] Final vs. Const
Null Aware Operators in Dart Programming
Dart mixin
Dart 2.12μ—μ„œ Null Safety μ‚¬μš© 방법

profile
DevelOpErUN μ„±μž₯일기🌈

1개의 λŒ“κΈ€

comment-user-thumbnail
2022λ…„ 9μ›” 12일

😍잘보고 κ°‘λ‹ˆλ‹€~~

λ‹΅κΈ€ 달기