조용한 담장

Dart : Generics 본문

Dart

Dart : Generics

iosroid 2019. 11. 22. 12:27

Dart 의 Generics 에 대해 살펴보자.

Dart 의 API documentation 에서 데이터 타입이나 클래스의 정의를 보면 <> 와 그 안에 'E, T, S, K, V' 같은 문자로 된 표현을 볼 수 있다.

Generics 를 사용하면 변수 타입을 명확히 표현할 수 있다는 장점과 반복되는 코드를 줄일 수 있다는 장점이 있다.

List<String> 식의 표현으로 string 타입의 값을 가지는 리스트라는 명확한 선언을 통해 잘못된 타입의 값 삽입을 막을 수 있다.

var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
names.add(42); // Error

여러가지 데이터 타입에 대해 동일한 동작을 해야 하는 코드가 있다면, 데이터 타입별로 코드를 생성할 필요 없게되어 코드를 줄일 수 있다.

// Object specific class
abstract class ObjectCache {
  Object getByKey(String key);
  void setByKey(String key, Object value);
}
// String specific class
abstract class StringCache {
  String getByKey(String key);
  void setByKey(String key, String value);
}
// Generic type
abstract class Cache<T> {
  T getByKey(String key);
  void setByKey(String key, T value);
}

Using collection literals

List, Set, Map 같은 collection 선언시에도 Generics 표현에 의해 타입이 명확해 진다.

List : [] -> <type>[]

Set : {} -> <type>{}

Map : { : } -> <type, type>{ : }

var names = <String>['Seth', 'Kathy', 'Lars'];
var uniqueNames = <String>{'Seth', 'Kathy', 'Lars'};
var pages = <String, String>{
  'index.html': 'Homepage',
  'robots.txt': 'Hints for web robots',
  'humans.txt': 'We are people, not machines'
};

Using parameterized types with constructors

여러 타입의 값을 파라미터로 받는 constructor 를 하나의 함수로 구현할 수 있다.

예1) Set<E>.from(Iterable elements) constructor

var nameSet = Set<String>.from(names);
var ageSet = Set<int>.from(ages);

예2) Map<K, V>() constructor

var views = Map<int, View>(); // integer keys and values of type View
var views = Map<double, String>(); // double keys and string values

Generic collections and the types they contain

Dart 의 generic 타입들은 Java 와 다르게 런타임 동안 타입의 정보가 없어지지 않는다.

자세한것은 Java 와 Dart의 공식 문서를 참조.

In contrast, generics in Java use erasure, which means that generic type parameters are removed at runtime. In Java, you can test whether an object is a List, but you can’t test whether it’s a List<String>.

var names = List<String>();
names.addAll(['Seth', 'Kathy', 'Lars']);
print(names is List<String>); // true

Restricting the parameterized type

generic 타입을 적용할 때 클래스의 파라미터의 타입을 제한할 수 있다.

extends 를 사용해 subclass 로 제한하는 방법이다.

class A {
  hello() => print('class A');
}
class B extends A {
  hello() => print('class B');
}
class C<T extends A> {
  hello() => print('class C ${T.runtimeType}');
}
class D {
  hello() => print('class D');
}
void main() {
  var a = C<A>();
  var b = C<B>();
  var c = C();
//   var d = C<D>(); // error ('D' doesn't extend 'A'.)
}

Using generic methods

generic 이 클래스에만 적용할 수 있었는데 method, function 의 파라미터에도 적용할 수 있다.

T first<T>(List<T> ts) {
  // Do some initial work or error checking, then...
  T tmp = ts[0];
  // Do some additional checking or processing...
  return tmp;
}

위 예제를 보면 함수의 리턴타입, argument 의 타입, 내부 변수의 타입에 generic type 이 쓰였다.

generic method

Reference

Generics - Dart

'Dart' 카테고리의 다른 글

Dart 2.7 release  (0) 2019.12.12
Dart : Generators  (0) 2019.11.22
Dart : Collections  (0) 2019.11.19
Dart : print  (0) 2019.11.04
Dart : Asynchronous programming  (0) 2019.10.24
Comments