Dart, 제너릭(Generic)
글. 수알치 오상문
API 문서에서 기본 배열 형은 리스트(List)인데, List<E> 형식인 것을 볼 수 있습니다. <…> 표기는 제너릭(또는 유형 매개변수) 형태의 리스트임을 알려줍니다. 대체로 유형 매개변수에는 E, T, S, K 및 V와 같은 단일 문자 이름을 사용합니다.
제너릭을 사용하는 이유
제네릭은 형식 안전을 위해 종종 필요하지만 다른 좋은 점도 있습니다.
- 제네릭 유형을 올바르게 지정하면 코드가 좋게 생성됩니다.
- 코드 중복을 줄일 수 있습니다.
리스트에 문자열만 포함되게 하려면 List <String>으로 선언 할 수 있습니다. 예를 들면 다음과 같습니다.
var names = <String>[];
names.addAll(['Seth', 'Kathy', 'Lars']); // 초기화
names.add(42); // 항목 자료형 오류!
제너릭을 사용하면 코드 중복을 줄일 수 있습니다. 아래 예제를 살펴보기 바랍니다.
abstract class ObjectCache {
Object getByKey(String key);
void setByKey(String key, Object value);
}
// 다른 인터페이스 (String 버전)
abstract class StringCache {
String getByKey(String key);
void setByKey(String key, String value);
}
// 나중에 숫자형 버전이 필요하면 같은 형식으로 또 만들어야 합니다.
// ...
제너릭을 이용하면 자료형 매개변수를 이용하면 간결하게 모두 표현할 수 있습니다. 자료형 매개변수 T를 이용하여 나중에 정의할 유형으로 대체되는 자리 표시를 합니다.
abstract class Cache<T> {
T getByKey(String key);
void setByKey(String key, T value);
}
컬렉션 리터럴 사용
리스트, 집합, 맵의 리터럴 상수값을 매개변수화 리터럴(Parameterized literals)로 다루는 예입니다. 매개변수화 리터럴은 기존 리터럴 표현 앞에 <형> (리스트 또는 집합에서 사용) 또는 <키형, 값형> (맵에서 사용)을 추가합니다.
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' };
생성자와 함께 매개변수화 형 사용
생성자를 사용할 때 유형을 하나 이상 지정하려면 클래스 이름 뒤에 유형을 꺾쇠 괄호 (<...>) 안에 넣습니다.
var nameSet = Set<String>.from(names);
// 다음 예제는 정수 키와 View 형 값을 갖는 맵을 만듭니다.
var views = Map<int, View>();
제너릭 컬렉션과 포함 형
var names = <String>[];
names.addAll(['Seth', 'Kathy', 'Lars']);
print(names is List<String>); // true
제너릭 형을 구현할 때, extends를 사용하여 매개변수 유형을 제한 할 수 있습니다.
class Foo<T extends SomeBaseClass> {
// 이곳에 구현...
String toString() => "Instance of 'Foo<$T>'";
}
class Extender extends SomeBaseClass {
// ...
}
SomeBaseClass 또는 하위 클래스를 제너릭 인수로 사용하는 것은 괜찮습니다.
var someBaseClassFoo = Foo<SomeBaseClass>();
var extenderFoo = Foo<Extender>();
제너릭 인수를 표시하지 않아도 됩니다.
var foo = Foo();
print(foo); // 'Foo<SomeBaseClass>'의 인스턴스
SomeBaseClass가 아닌 유형을 지정하면 오류가 발생합니다.
var foo = Foo<Object>(); // 오류!
제너릭 메서드 사용
Dart 초기 버전의 제너릭 지원은 클래스로 제한되었습니다. 이제 제너릭 메서드에서는 메서드 및 함수 인수를 허용합니다.
T first<T>(List<T> ts) {
// 초기화 작업 또는 오류 검사 등 처리...
T tmp = ts[0];
// 추가 검사나 다른 처리...
return tmp;
}
첫째 (<T>)의 제네릭 형식 매개변수를 사용하면 여러 위치에서 형식 인수 T를 사용할 수 있습니다.
- 함수 반환형 지정
- 전달인수의 형 지정 (List<T>)
- 지역변수의 형 지정 (T tmp).
<이상>
'Dart' 카테고리의 다른 글
Dart, 비동기 지원 (Asynchrony) (0) | 2021.06.17 |
---|---|
Dart, 라이브러리와 가시성 (0) | 2021.06.17 |
Dart, 클래스 변수와 메서드 (0) | 2021.06.17 |
Dart, 클래스에 기능 추가하기(mixin) (0) | 2021.06.17 |
Dart, 열거형 (Enumerated type) (0) | 2021.06.17 |