N coding
Dart : what is extenstion ? extension keyword 본문
Dart Extension Keyword
다트 extension이란?
https://blog.naver.com/nywoo19/222443746252
https://summer-milkshake-01b.notion.site/Extension-on-keyword-3f2d9544b55a41b789e3fadb2d851d65
다른 사람의 API를 사용하거나, 광범위하게 사용되는 라이브러리를 구현할 때
API를 수정하는 것이 비효율적이거나 불가능한 경우가 있다.
하지만 그래도 어떤 기능을 추가하고 싶은 경우,..!
예를 들어,
int.parse('42')
로 사용하는 대신
'42'.parseInt()
와 같이 String에 기능을 추가해서 사용하고 싶을 수도 있다.
이러한 경우에 extenstion 을 사용한다.
method 뿐만 아니라 member(getter, setter, operator) 등도 정의가 가능하다. field는 안 됨
extension은 이름도 가질 수 있다.
위의 예제를 가능하게 하는 extension은
extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
}
와 같이 구현이 가능하다.
Using extension methods
extension method는 라이브러리 안에 있다.
그냥 그 라이브러리를 import하고 일반 메소드 처럼 사용하면 된다.
// Import a library that contains an extension on String.
import 'string_apis.dart';
// ···
print('42'.padLeft(5)); // Use a String method.
print('42'.parseInt()); // Use an extension method.
explicit하게도 사용가능
Ext1(list).bubbleSort() // Explicit, like it's a wrapper class.
list.bubbleSort() // Implicitly, like it extends the type.
static and dynamic types
extension method는 dynamic type의 변수에서는 사용이 불가능하다. receiver의 static type을 기반으로 extension method가 확인?확정?되기때문에 dynamic type에서는 작동하지 않는다.
extension method가 static resolution으로 한정하게 되면 object를 runtime에 검사할 필요가 없어서 다른 static 함수를 호출하는 것 만큼이나 빠르다, 또한 까다로운 코너 케이스도 발생하지 않을 수 있다.
dynamic d = '2';
print(d.parseInt()); // Runtime exception: NoSuchMethodError
Dart의 type inference로는 잘 작동한다. Dart가 var을 String 타입으로 infer했기 때문에 아래와 같은 코드는 가능!
var v = '2';
print(v.parseInt()); // Output: 2
API conflicts
만약 extension member들이 다른 interface나 다른 extension member와 conflict 가 난다면 몇 가지 옵션이 있다.
- import 방식을 바꾼다.
// Defines the String extension method parseInt().
import 'string_apis.dart';
// Also defines parseInt(), but hiding NumberParsing2
// hides that extension method.
import 'string_apis_2.dart' hide NumberParsing2;
// ···
// Uses the parseInt() defined in 'string_apis.dart'.
print('42'.parseInt());
- extension을 명시적으로 적용
// Both libraries define extensions on String that contain parseInt(),
// and the extensions have different names.
import 'string_apis.dart'; // Contains NumberParsing extension.
import 'string_apis_2.dart'; // Contains NumberParsing2 extension.
// ···
// print('42'.parseInt()); // Doesn't work.
print(NumberParsing('42').parseInt());
print(NumberParsing2('42').parseInt());
- 두 extension의 이름이 같다면 import에 namespace를 준다.
아래를 보면 알 수 있듯이 string_apis_3에만 있는 extension method는 prefix이름을 주지 않아도 implicitly하게 사용가능하다.
// Both libraries define extensions named NumberParsing
// that contain the extension method parseInt(). One NumberParsing
// extension (in 'string_apis_3.dart') also defines parseNum().
import 'string_apis.dart';
import 'string_apis_3.dart' as rad;
// ···
// print('42'.parseInt()); // Doesn't work.
// Use the ParseNumbers extension from string_apis.dart.
print(NumberParsing('42').parseInt());
// Use the ParseNumbers extension from string_apis_3.dart.
print(rad.NumberParsing('42').parseInt());
// Only string_apis_3.dart has parseNum().
print('42'.parseNum());
Implementing
extension <extension name> on <type> {
(<member definition>)*
}
예시
extension NumberParsing on String {
int parseInt() {
return int.parse(this);
}
double parseDouble() {
return double.parse(this);
}
}
해당 library에서만 visible하게 하고 싶으면
extension name을 제거하거나 name을 underscore로 시작하게 한다.
( _NumberParsing) 처럼
generic extensions
generic type parametere도 가질 수 있다.
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)];
}
결론
- 언제 사용하냐?
- 이미 존재하는 API에 메소드 몇 개를 추가하고 싶은 경우
- 어떻게 사용하냐?
- extension을 정의하고 그냥 일반 메소드 처럼 사용하면 된다.
Examples
추가 링크
Dart extension method fundamentals
Why doesn't extension work when invoked through dynamic?
language/feature-specification.md at master · dart-lang/language
'Dart&Flutter' 카테고리의 다른 글
Flutter : How to develop flutter on tizen? (0) | 2022.01.20 |
---|---|
Dart : async/await/Future (0) | 2022.01.20 |
Flutter : Flutter onDrawerSlide 구현하기 (0) | 2022.01.20 |
Flutter : FFI (0) | 2022.01.20 |
Dart : enum with values (enum-like class) (0) | 2022.01.20 |