반응형

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

+ Recent posts