Adding features to a class: mixins
https://dart.dev/guides/language/language-tour#adding-features-to-a-class-mixins
Mixins 는 클래스 코드를 재사용하는 방법이다.
사용하려면 with 키워드와 함께 mixin 이름을 지정해준다.
mixins 를 구현하려면 Object 를 상속하는 class 를 만들고 생성자를 구현하지 않는다. (매개변수가 없는 기본 생성자를 사용한다.)
class 키워드 대신 mixin 을 사용한다.
특정 타입에 해당하는 mixin 을 지정할 수 있다.
뒤에 on 키워드와 함께 type 을 써주면 된다.
Class variables and methods
https://dart.dev/guides/language/language-tour#class-variables-and-methods
클래스 변수, 메서드를 만들려면 static 키워드를 사용한다.
Static variables
static 변수는 상태와 상수에 유용하다.
static 변수는 사용되기 전까지 초기화되지 않는다.
Static methods
static 메서드는 인스턴스의 연산이 아닌다. 그래서 this 를 사용할 수 없다.
static 메서드는 컴파일 타임 상수로 사용할 수 있다.
예를 들면 static 메서드를 상수 생성자에 매개변수로 넘길 수 있다.
Generics
https://dart.dev/guides/language/language-tour#generics
API 문서에서 List type 을 보게 되면 List<E> 와 같은 것을 보실 수 있다.
<...> 은 List 가 제네릭 타입이라는 표시이다.
기본 컨벤션에 따르면 대부분의 타입 변수는 한문자로 사용한다.
Why use generics?
제네릭은 보통 타입 안정성을 요구한다. 그러나 그건 더 많은 이득이 있다.
- 적절하게 제네릭타입을 지정하면 생성되는 코드가 더 좋을 수 있다. (컴파일 후 최적화 과정 중에서 코드가 더 좋아진다는 의미인 듯)
- 코드 중복을 줄이기 위해 사용할 수 있다.
만약 list 에 String 만 포함한다면 List<String> 이다.
실수로 String 이 아닌 값을 넣는 것을 발견할 수 있다. (컴파일 오류)
제네릭을 사용하는 다른 이유는 코드 중복을 제거하는 것이다.
정적 분석을 여전히 이용하면서 다양한 타입에 대해서 하나의 인터페이스와 구현을 공유하도록 한다.
Using collection literals
List, set, map literals 는 매개변수화 될 수 있다.
매개변수화된(Parameterized) literals 는 이미 본 것과 같은 형태이다.
중/대 괄호가 시작하기 전에 <type>, <keyType, valueType> 을 추가하는 것을 제외하는 형태로
Using parameterized types with constructors
생성자를 사용할 때 하나 이상의 타입을 지정하는 경우 클래스명 뒤에 < > 사이에 타입을 지정한다.
Generic collections and the types they contain
Dart 제네릭 타입은 구체적이다. 타입에 대한 정보를 런타입까지 가져간다.
반대로 자바는 런타임 때 제네릭 정보가 제거된다.
Restricting the parameterized type
제네릭 타입을 구현할 때 타입의 제약을 원할 것이다.
이때는 extends 키워드를 이용할 수 있다.
<T extends SomeBaseClass>
라고 하면 SomeBaseClass 를 상속받은 하위 클래스 중 하나이다 라는 의미이다.
Using generic methods
메서드에서도 제네릭을 사용할 수 있다.
- 메서드의 return 타입
- 매개변수 타입
- 지역 변수 타입
Libraries and visibility
https://dart.dev/guides/language/language-tour#libraries-and-visibility
import, library 키워드는 모듈화 된, 공유 가능한 코드를 만드는데 도움을 준다.
Using libraries
다른 라이브러리의 범위를 지정하여 import 를 사용할 수 있다.
import 의 매개변수는 libraray 를 지정하는 URI 이다.
내장 라이브러는 특별히 dart: scheme 을 가진다.
다른 라이브러리는 파일 시스템의 path 나 package: scheme 을 사용할 수 있다.
package: scheme 은 pub tool 과 같은 패키지 매니저에 의해서 제공되는 라이브러리를 지정한다.
Specifying a library prefix
만약 identifier 가 충돌 나는 두 개의 라이브러리를 import 하려고 한다면 하나 이상의 라이브러리에 대해서 prefix 를 지정할 수 있다.
Importing only part of a library
만약 라이브러리의 특정 부분만 사용하고 싶다면 선택적으로 사용할 수 있다.
import 마지막에 show, hide 키워드를 사용해서 할 수 있다.
Lazily loading a library
https://dart.dev/guides/language/language-tour#asynchrony-support
lazy/deferred loading 은 웹앱에서 필요에 의해서 라이브러리를 로드할 수 있도록 허용한다.
- 웹앱의 초기 시작 시간을 줄일 수 있다.
- A/B 테스트팅을 할 수 있다.
- 드물게 필요한 기능을 로드할 때 사용한다.
사용하라면 import 끝에 deferred as 키워드를 사용한다.
만약 해당 라이브러리가 필요해지면 loadLibrary() 함수로 로드할 수 있다.
loadLibrary 는 여러 번 호출되어도 한 번만 로드한다.
deffered loading 을 사용할 때 주의해라
- deferred 라이브러리의 상수는 라이브러리가 로드되기 전까지 사용할 수 없다.
- import 라이브러리에서 deferred 라이브러리의 type 을 사용할 수 없다. 인터페이스 타입을 import, deffered 라이브러리로 다 옮김는 것을 고려해야 한다... (이 부분은 잘 이해가 안되는데... 아마도 lazy 이다 보니 type 을 바로 쓸 수 없는 이슈인 듯하다. 그래서 interface 를 만들어서 사용하려고 하는 측으로 이동하라고 하는 듯하다.)
- dart 는 deffered 를 네임스페이스처럼 사용할 수 있도록 하기 위해 암시적으로 loadLibrary 를 네임스페이스에 넣었다.
Asynchrony support
Dart 라이브러리는 Futer, Stream Object 를 리턴하는 함수들이 있다.
이 함수들은 비동기이다. 연산이 끝나길 기다리지 않고 시간이 걸리는 연산을 설정 후 리턴한다.
비동기 프로그래밍에는 async await 키워드가 있다. 동기 코드처럼 비동기 코드를 사용할 수 있도록 해준다.
Handling Futures
완료된 Future 의 결과를 원할 때 두 가지 선택이 있다.
- async, await 를 사용한다.
- Future API 를 사용한다.
async, await 를 사용한 코드는 비동기이지만 동기 코드와 비슷하다.
await 를 사용하기 위해서는 코드는 async 함수에 있어야 한다.
await 를 사용하는 코드에서 error, cleanup 을 처리하기 위해 try, catch, finally 를 사용한다.
async 함수 안에서 await 를 여러번 사용할 수 있다.
await 를 사용한 결과는 항상 Future 이다. 만약 그렇지 않다고 해도 Future 에 의해 감싸 진다.
Future 객체는 object 를 리턴할 것이라고 약속한다.
await 를 사용하는데 컴파일 타입 에러가 발생한다면 await 가 async 함수 안에 있는지 확인해라.
Declaring async functions
async 함수는 async 가 표시되어 있는 함수이다.
함수에 async 키워드를 붙이면 Future 를 리턴하게 만든다.
함수 안에서 Future API 를 사용할 필요는 없다.
Dart 는 필요하면 Future 객체를 만든다.
만약 함수가 값을 리턴하지 않는다면 Future<Void> 를 리턴하도록 만든다.
Handling Streams
스트림에서 값을 얻길 원할 때 두 가지 선택이 있다.
- async, await for 를 사용한다. (종료되는 스트림이어야 하는듯)
- Stream API 를 사용한다.
await for 은 다음과 같이 처리된다.
- 스트림이 값을 emit 하기 전까지 기다린다.
- emit 된 값과 함께 loop 의 코드를 실행한다.
- 스트림이 종료될 때까지 1, 2를 반복한다.
await for 를 종료하기 위해서는 break, return 을 사용한다.
만약 await for 를 사용하는데 컴파일 에러가 발생한다면 await for 가 async 함수 안에 있는지 확인해라.
Generator
dart.dev/guides/language/language-tour#generators
연속된 값을 lazy 하게 생산할때 generator 함수 사용을 고려할 수 있다.
dart 는 두가지의 generator 함수를 제공 한다.
- Synchronous generator, Iterable object 를 리턴한다.
- Asynchronous generator, Stream object 를 리턴한다.
synchronous generator 함수를 구현하려면 함수에 sync* 를 표시하고 값을 전달하기 위해 yield 를 사용한다.
aysnchronous generator 함수를 구현하려면 함수에 async* 를 표시하고 값을 전달하기 위해 yield 를 사용한다.
만약 generator 함수가 재귀이면 yield* 를 사용하여 성능 향상을 할 수 있다.
Callable classes
dart.dev/guides/language/language-tour#callable-classes
call() 함수를 구현하여 인스턴스를 함수처럼 호출하는 것을 허용한다.
'Programming > Dart & Flutter' 카테고리의 다른 글
Flutter 1일 차 - Flutter for iOS devs (1/8), Views (0) | 2020.07.26 |
---|---|
Dart 7일 차 - Language Tour (7/7) (0) | 2020.07.26 |
Dart 5일 차 - Language Tour (5/7) (0) | 2020.07.25 |
Dart 4일 차 - Language Tour (4/7) (0) | 2020.07.24 |
Dart 3일 차 - Language Tour (3/7) (0) | 2020.07.22 |