티스토리 뷰

flutter

다트언어 - 1

4whomtbts 2020. 1. 1. 02:12

플러터 해보면서 좋은 것 같아서 다트 doc을 번역해보면서 개인적인 경험이나 느낌에 비추어서 써보겠습니다.

각잡고 읽으면서 학습하시려는 분 보다는, 그냥 Dart가 어떤 스타일이고 어떤 철학을 추구하는지 관심이 있어서

심심풀이로 읽으시는게 좋을 것 같습니다!.

 

(*) 는 역자 주 라고 생각하시면 됩니다

https://dart.dev/guides/language/language-tour

 

A tour of the Dart language

A tour of all of the major Dart language features.

dart.dev

중요한 개념들

- 모든 변수들은 object입니다. 그리고 모든 object는 class의 인스턴스입니다. 심지어 숫자, 함수, null 객체마저도

Object class로 부터 상속된 객체입니다 

(* Java 랑 굉장히 비슷한 것 같습니다. 실제로 flutter 예제를 몇 개 만들어보면서 문법을 하나도 찾아보지 않고

  만들 수 있었습니다. )

- Dart가 강한 타입 언어이긴 하지만, 타입 어노테이션은 선택적입니다. 왜냐하면 Dart는 타입 추론이 가능하기 때문입니다.   만약에 어떤 타입인지조차 모를경우(no type is expected) 'dynamic'이라는 special type을 사용하세요.

https://dart.dev/guides/language/effective-dart/design#do-annotate-with-object-instead-of-dynamic-to-indicate-any-object-is-allowed

 

Effective Dart: Design

Design consistent, usable libraries.

dart.dev

(* dynamic에 대해 위의 문서를 보고 따로 알아보았습니다. 코드로보건데, C언어의 void pointer랑 비슷하고, Java 나 Go에서 type reflection 개념인 것 같습니다)

- Dart는 Generic type을 지원합니다. List<int> 나 List<Dynamic> 처럼요(* 맘에듭니다..) 

- Dart는 top-level 함수를 지원합니다. 또한, 함수는 클래스나 객체에 묶여있습니다. 또, 함수안에 함수를 만들 수 있습니다.(* 이부분은 javascript랑 비슷한 것 같습니다) 

- 이전항과 비슷하게, Dart는 top-level variable을 지원합니다. 

- Dart는 public, protected, private같은 access qualifier가없습니다. 대신 맨 앞에 underscore('_')를 붙여서 

  private 함수로 만들 수 있습니다.(* 이 부분은 좀 맘에 안드네요ㅜ)

- Dart에는 표현식(*원문에서 expression, 런타임 값을 갖는) 과 선언문(런타임 값이 없는) 이 있습니다

  예를들어, C나 Java에 있는 삼항연산자( ?: ) 가 있습니다(* 어떤 언어에는 없어서 아쉬웠던 기억이 있네요)

키워드

이 부분에서는 대부분 다른 언어에는 없지만 있는 예약어, 반대로 대부분의 언어에는 있지만 Dart에서는

존재하지 않는 키워드만 다뤄보겠습니다.

1. is, as  

  obj is T 의 표현식은 obj가 T타입일 경우에 true를 반환합니다. 당연하게도, obj is Object는 항상 true입니다.

  as는 타입캐스팅 예약어입니다. (emp as Person).firstName = 'Bob'; 과 같이 사용합니다.

2.대입연산자

  a = value; 식은 당연히 있는데 특이한건 b ??= value; 도 있습니다. 이것은 b가 null이면 b에 value를 대입하고

  b가 null이 아니라면 b는 원래 값을 유지합니다. (* 유용하다고 생각되긴 하지만, 개인적으로 굉장히 위험한

연산자라고 생각듭니다.)

3.show

https://dart.dev/guides/language/language-tour#importing-only-part-of-a-library

 

A tour of the Dart language

A tour of all of the major Dart language features.

dart.dev

굉장히 특이한 에약어인데, 

import 'package:lib1/lib1.dart' show foo; 라고 하면, lib1에서 오직 foo만 import한다고 합니다.

import 'package:lib2/lib2.dart' hide foo; 라고 하면 lib1에서 foo 빼고 모두 import합니다.

Lazy Loading 도 있습니다. 

필요할 때 loading하는 기능입니다. 아래의 경우에 사용합니다.

1. 웹 어플리케이션의 시작 시간을 줄이기 위해

2. A/B 테스트를 진행하기 위해

3. 잘 사용되지 않는 기능을 사용하는 경우

 

3. Asynchrony Support 의 async, await 예약어

https://dart.dev/guides/language/language-tour#asynchrony-support

 

A tour of the Dart language

A tour of all of the major Dart language features.

dart.dev

(*특이하게 정적타이핑언어에, async 와 await이라는 예약어가 있습니다. Java나 C도 있긴 하지만 대부분 

 execute나, join을 사용하는데 익숙해서 새롭게 느껴집니다.) 

Dart library는 Future와 Stream을 반환하는 함수들이 많습니다. 이러한 함수들은 비동기적인데, time-consuming한

작업들이 끝나고나서 실행되기 위해서 사용됩니다.(예를 들어 I/O). 작동이 끝날때까지 기다릴 필요가 없게하기

위해서입니다. 

(* async, await 은 흥미로운 부분이니 따로 글을 써야겠습니다.) 

 

4. factory 예약어

https://dart.dev/guides/language/language-tour#factory-constructors

 

A tour of the Dart language

A tour of all of the major Dart language features.

dart.dev

factory 예약어는 생성자이긴 하지만 항상 새로운 인스턴스를 만들어내지는 않습니다. 예를 들어서, 

factory 생성자는 cache된 인스턴스를 반환하기도 하고, subtype의 인스턴스를 반환하기도 합니다.

(* 싱글턴 패턴을 사용하고자 할 때 유용하긴 하겠습니다만, 위험해보이기도 합니다.)

 

5. typedef 예약어

https://dart.dev/guides/language/language-tour#typedefs

 

A tour of the Dart language

A tour of all of the major Dart language features.

dart.dev

(* Java에 없어서 너무 아쉬웠던 typedef 가 있습니다!)

typedef Compare<T> = int Function(T a, T b); 

(*위와 같이 사용합니다. 제너릭도 쓸 수 있어서 엄청 유용하겠네요)

 

6. var 

(*var 은 여러 언어에서 사용하지만(Go나 Rust) Dart에서 사용하는 방식은 좀 다른 것 같습니다)

var 은 기본적으로 레퍼런스를 저장합니다.

var name = 'Bob'; 이라고 선언했을 때,  Bob이란 값을 가지고 있는 String을 가리키는 name이란 이름을 갖는 객체를 가리킵니다. 

(*var를 사용하지 않으면 C언어 처럼 )

String name = 'Bob'; 라고 쓸 수 있습니다.

7. getter 와 setter 

https://dart.dev/guides/language/language-tour#getters-and-setters

 

A tour of the Dart language

A tour of all of the major Dart language features.

dart.dev

(* kotlin 과 비슷한 getter 와 setter를 제공합니다.  특별한 설명이 필요없고, 용례를 링크를 통해 확인하시는게 낫겠습니다.) 

여기부터는 그대로 번역한 내용이 아닙니다.

Default value

초기화 되지 않은 변수는 모두 null을 갖습니다(* 현대의 모든 언어들이 어떻게든 null을 쳐내려고 한다는 점에 비추어 봤을 때 신기합니다)

Final 과 Const

특이하게 Final과 const가 같이 있습니다.  인스턴스 변수는 final은 되지만 const는 안 됩니다. Final 인 인스턴스 변수는 반드시 생성자 본체 이전에 초기화되어야 합니다.(즉, 선언과 할당이 동시에 되어있어야 한다는 것 입니다)  

생성자 파라미터를 이용하던가, 아니면 initializer list 를 사용하면 됩니다.

final name = 'Bob'; // 가능

final String nickname = 'Bobby'; // 가능

name = 'Alice' // 불가능

const는 compile-time 변수입니다. 

숫자들에 관해

십진수 값은 기본적으로 double로 간주됩니다. 

String

String 다루기가 꽤 편한 것 같습니다.

var s1 = '이렇게 '

'선언해도 '

'하나로 붙습니다.'

asssert(s1 == '이렇게 선언해도 하나로 붙습니다'); // true;

var s2 = '더하기 연산자 + 도 '  + '이렇게 잘 됩니다.';

assert(s2 == '더하기 연산자 +도 이렇게 잘 됩니다.'); // true;

var s1 = '''

이렇게 apostrophe를 3개 쓰면

띄어쓰기 한 대로 띄어쓰기가 됩니다 

''';

collection if, for

특이한 문법이 있네요 Dart 2.3부터는 아래의 문법이 제공됩니다.

var nav = [

  'Home',

 'Furniture',

 'Plants',

 if(promoActive) 'Outlet' 

]; 

var listOfInts = [1, 2, 3];

var listOfStrings = [

 '#0',

for ( var i in listOfInts) '#$i'

];

이건 맘에 쏙 드는 문법이네요.

 

Set

var halogens = {'fluorine', 'chlorine', 'bromine'};

이렇게 쓸 수 있습니다.

빈 set을 만들기 위해서는, var names = <String>{}; 으로 하면 됩니다.

final constantMap = const {

  2: 'helium',

 10: 'neon'

};

위와같이 만들면 immutable set으로 쓸 수 있습니다.

 

익명함수

var list = ['apples', 'bananas', 'oranges' ];

list.forEach((item) {

  printf('${list.indexOf(item)}: $item');

});

Cascade notation(..)

정말 좋은 문법 중 하나 같습니다.

 Cascade는 같은 객체에 대해 순차적인 오퍼레이션을 취할 수 있도록 해줍니다. 

 querySelector가 어떠한 Object를 반환하는 함수라고 하면

위와같이 사용할 수 있습니다. 이 코드는 아래의 코드와 동일합니다.

생성자

위의 코드를 보면, 

Point(num x, num y) {

   this.x = x;

   this.y = y;

}  

코드를 줄이기 위해 Point(this.x, this.y); 를 사용해서 코드를 깔끔하게 만들었습니다.

 

서브클래스의 생성자는 슈퍼클래스의 이름과 매개변수가 없는 생성자를 호출합니다. 슈퍼클래스의 생성자는 

서브클래스의 생성자 본체에서 호출됩니다. 만약에 서브클래스의 생성자에 초기화 리스트가 있다면 

생성자 본체 전에 호출됩니다.

만약에 슈퍼클래스가 이름과 매개변수가 없는 생성자가 없다면, 반드시 자식클래스에서 명시적으로

호출해주어야 합니다. 

참고로, Dart에서는 생성자가 이름을 가질 수 있습니다 위의 코드에서 보면

Employee.fromJson 이라고 명명했죠. 처음 봤을 때는 이게 무슨 생뚱맞은 문법인가 생각했는데

Java 프로그래밍을 할 때 생각해보면, of 나 from** 같은 사실상 생성자의 역할을 하는 static method를

idiom 처럼 사용하곤 하는데, Dart에서는 아예 그런 부분을 문법으로 제공해준다고 볼 수 있습니다. 

생성자 리스트

C++ 처럼 생성자 리스트를 사용할 수 있습니다. 

 

'flutter' 카테고리의 다른 글

[KOR,ENG]Flutter todo 만들기 - 2  (0) 2020.01.02
[KOR,ENG]Flutter todo - 1  (0) 2020.01.01
댓글