목적
- 다른 벤더에서 만든 라이브러리의 API를 직접 수정하지 않고 내가 원하는 메서드를 몇개 추가하고 싶을 때 사용 가능하다.
- 일반적인 언어에서 타인의 API 를 변경하는 것이 불가능한 경우가 많다.
- 원래는 헬퍼 함수나 래퍼 클래스를 이용해 해결하던 문제를 Extension methods 로 해결할 수 있는 것이다.
예시 1: 파싱
- 문자열에서 숫자로 변환하는
parseInt()
함수가 있었으면 할 때
확장이 포함된 라이브러리 임포트하기
- 라이브러리를 임포트하고 원래 있던 메서드인것처럼 사용하면 된다.
import 'string_apis.dart';
// ···
print('42'.parseInt()); // Extension 메서드 사용.
extension
키워드를 이용해 직접 구현하기
extension ... on
키워드를 이용하여 직접 작성할 수 있다.- 기존에 작성된 메서드를 오버라이드할 수도 있다.
- API 충돌이 발생할 때 유용하다
extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
// ···
}
dynamic
타입에선 사용이 불가능하다
dynamic
타입에서 확장 메서드 사용을 시도하는 경우 에러가 발생한다.
dynamic d = '2';
print(d.parseInt()); // 런타임 예외: NoSuchMethodError
var
에선 사용이 가능하다
- 확장 메서드는 Dart 의 타입 추론을 사용해서
var
에선 사용이 가능하다.
var v = '2';
print(v.parseInt()); // Output: 2
참고: 다트의 타입 시스템
API 충돌 해결하기
show
혹은 hide
로 해결하기
hide
를 통해NumberParsing
이라는 구체적인 확장에 딸린 메서드들을 숨길 수 있다.
import 'string_apis.dart';
// hide를 사용하여 NumberParsing2의 확장 메서드를 숨기기.
// 내부에 parseInt() 가 들어있다고 가정한다.
import 'string_apis_2.dart' hide NumberParsing2;
// 'string_apis.dart' 에 정의된 parseInt()를 사용한다.
print('42'.parseInt());
확장 명시적으로 사용하기
extension
의 이름을 구체적으로 사용한다.
import 'string_apis.dart'; // Contains NumberParsing extension.
import 'string_apis_2.dart'; // Contains NumberParsing2 extension.
print(NumberParsing('42').parseInt());
print(NumberParsing2('42').parseInt());
별칭 정하기
import 'string_apis.dart';
import 'string_apis_3.dart' as rad;
print(NumberParsing('42').parseInt());
print(rad.NumberParsing('42').parseInt());
// string_apis_3.dart만 parseNum()을 가지고 있어서 이 부분은 겹치지 않음
// 별칭을 사용했더라도 확장 메서드 사용이 가능한 점은 눈여겨볼만하다.
print('42'.parseNum());
확장 메서드 구현 방법
extension <extension name>? on <type> {
(<member definition>)*
}
예시
- 연산자, getter, setter 혹은 메서드가 확장의 멤버가 될 수 있다.
- 확장도 정적 필드와 정적 헬퍼 메서드를 가질 수 있다.
extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
double parseDouble() {
return double.parse(this);
}
}
익명 확장 메서드
- 선언된 라이브러리 내에서만 사용 가능한 확장 메서드다
extension on String {
bool get isBlank => trim().isEmpty;
}
제네릭 확장 메서드
- 확장 메서드도 제네릭 타입을 가질 수 있다.
extension MyFancyList<T> on List<T> {
int get doubleLength => length * 2;
List<T> operator -() => reversed.toList();
List<List<T>> split(int at) => [sublist(0, at), sublist(at)];
}
레퍼런스
추가 리소스
반응형
'Dart' 카테고리의 다른 글
다트 (Dart) 언어의 생성자 (Constructors) 정리 (0) | 2023.10.13 |
---|---|
다트(Dart) 언어의 클래스(Class) 정리 (0) | 2023.10.12 |
다트(Dart) 언어의 클래스 제어자 (Class modifier) 정리 (0) | 2023.10.12 |
다트의 오류 처리 방식 (1) | 2023.10.08 |
다트 (Dart) 변수, 상수 선언 방식 (0) | 2023.10.08 |