728x90
다른 언어에도(JAVA, Typescript, ...) 존재하는 제네릭이 Dart에도 존재한다.
일반적인 제네릭의 정의는 아래와 같다.
제네릭은 데이터 형식에 의존하지 않고, 하나의 값이 여러 다른 데이터 타입들을 가질 수 있는 기술에 중점을 두어 재사용성을 높일 수 있는 방식이다.
Why use generics?
제네릭은 자주 타입보장이 필요할 때 사용되지만 코드가 실행가능하도록 많은 이점을 가지고 있다.
- 제네릭타입을 적절하게 지정하면 코드가 더 잘 생성된다.
- 제네릭을 사용하여 코드 중복을 줄일 수 있다.
예를들어 객체에 대한 캐시용 인터페이스를 생성해보자.
abstract class ObjectCache {
Object getByKey(String key);
void setByKey(String key, Object value);
}
사용하다보니 객체가 아닌 다른 타입용 인터페이스가 필요해지면 아래와 같이 타입에 맞추어 다른 인터페이스를 생성해야한다.
abstract class StringCache {
String getByKey(String key);
void setByKey(String key, String value);
}
abstract class NumberCache {
Number getByKey(String key);
void setByKey(String key, Number value);
}
...
이럴 때 제네릭은 이 모든 인터페이스 생성에 대한 문제를 해결해준다.
abstract class Cache<T> {
T getByKey(String key);
void setByKey(String key, T value);
}
Using collection literals
리스트, 세트, 맵 리터럴은 매개변수화 되어있다. 무슨 뜻인지 잘 모르겠다. 예시로 알아보자.
void main() {
/// 타입을 지정하지 않고 선언을 하면
/// 런타임 시점에 타입추론을 통해서
/// Object타입의 배열로 정의된다.
final coll1 = ["hi", 1, 2, true]; // JSArray<Object>
/// 아래와 같이 선언시, 문자열 배열이기 때문에
/// 에러가 발생한다.
/// The element type 'int' can't be assigned to the list type 'String'.
final coll2 = <String>["hi","hello", 1];
final coll3 = <String>["say", "yes"]; // JSArray<String>
final coll4 = <String>{'say', 'yes'}; // _LinkedHashSet<String>
final coll5 = <String, String>{ // JsLinkedHashMap<String, String>
'name': 'womillism',
'hi': 'hello',
};
}
다음과 같이 생성자에 매개변수화된 타입을 사용할 수도 있다.
var nameSet = Set<String>.from(names);
var views = Map<int, View>();
Restricting the parameterized type
제네릭 타입을 구현할 때 인자로 제공되는 타입에 대한 제한을 하고 특정 타입의 하위 타입만 가능하도록 하고 싶을 수 있다.
이때 extends 키워드를 사용하여 할 수 있다.
class Foo<T extends Object> {
// T에 어느 타입이든 가능하지만 null이 아니어야 합니다.
}
class Foo<T extends SomeBaseClass> {
// 구현은 여기서...
String toString() => "Instance of 'Foo<$T>'";
}
var someBaseClassFoo = Foo<SomeBaseClass>();
var extenderFoo = Foo<Extender>();
메소드와 함수에서도 마찬가지로 제네릭을 사용할 수 있다.
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;
}
- 함수의 반환 타입 (T)
- 인자의 타입 (List<T>)
- 로컬 변수의 타입 (T map)
728x90
300x250