한글로 번역하면 확장 메서드
.
API, 외부 라이브러리, 내가 쓰는 기본 class들에 커스텀해서 추가 기능을 붙이고 싶다면?
바로 extension method
를 사용하면 됩니다.
혹시 something.toString();
을 사용해 봤다면? 이미 반 쯤은 어떤 느낌인지 알고 있을 것 같네요:)
🍀 공식 문서 : https://dart.dev/language/extension-methods
extension method
란?extension method
는 이미 존재하는 클래스의 내부 구현을 변경하지 않고 추가 기능을 붙일 수 있는 기능이다.
Dart 언어에서 제공하는 이 기능은 라이브러리나 프레임워크의 클래스를 확장하거나, 기존 코드에 영향 없이 추가적인 기능을 구현하고자 할 때 유용함니다.
extension method
의 핵심은 코드 가독성 향상과 재사용성 향상 입니다.
extension method
사용시 주의사항dynamic
타입으로 선언한 변수에는, 이후 코드 내에서 해당 변수의 타입이 명확하더라도 확장 메서드 사용이 불가능합니다.dynamic
은 동적 타입으로 컴파일시 타입 체크를 하지 않기 떄문입니다.var
타입으로 선언하면 초기화 시점에 타입을 결정하고 동작하기 때문에 확장 메서드 사용이 가능합니다.extension method
의 실전 활용String
클래스 확장하기extension StringExtension on String {
// 이제 모든 String값에 something.reverse(); 를 사용할 수 있습니다.
String reverse() {
return split('').reversed.join('');
}
}
void main() {
String text = 'Flutter';
print(text.reverse()); // rettulF
}
class Point {
int x;
int y;
Point(this.x, this.y);
}
extension PointExtension on Point {
// Getter: 원점(0, 0)으로부터의 거리
double get distanceFromOrigin {
return (x * x + y * y).toDouble().sqrt();
}
// Setter: 거리 값을 기반으로 위치 설정
set distanceFromOrigin(double distance) {
x = (distance / 1.414).round(); // 간단히 대각선 기준으로 값 설정
y = (distance / 1.414).round();
}
// + 연산자 오버로딩: 두 Point 객체의 x, y 값을 더하기
Point operator +(Point other) {
return Point(x + other.x, y + other.y);
}
}
void main() {
Point p = Point(3, 4);
print(p.distanceFromOrigin); // 5.0
p.distanceFromOrigin = 10;
print('${p.x}, ${p.y}'); // 7, 7
Point p1 = Point(3, 4);
Point p2 = Point(1, 2);
Point p3 = p1 + p2; // + 연산자 오버로딩
print('${p3.x}, ${p3.y}'); // 4, 6
}
IntExtension
확장을 통해 int 타입에 addWithHelper()라는 확장 메서드를 추가했습니다.class MathUtils {
// static helper method: 두 값을 더하는 함수
static int add(int a, int b) {
return a + b;
}
}
extension IntExtension on int {
// 확장 메서드: 두 숫자를 더하기 위해 static helper method 사용
int addWithHelper(int other) {
return MathUtils.add(this, other); // static helper method 호출
}
}
void main() {
int a = 10;
int b = 20;
// 확장 메서드 호출
print(a.addWithHelper(b)); // 출력: 30
}
extension StringExtension on String {
// int times이라는 argument를 받아서 여러 번(times) 문자열을 출력하는 확장 메서드
String repeat(int times) {
return this * times;
}
}
void main() {
String text = 'Flutter';
print(text.repeat(3)); // FlutterFlutterFlutter
}
someString.repeat(3)
의 형태로 매개변수를 담아서 함수를 사용할 수 있습니다. String a = "a";
ExtensionA(a).change();
ExtensionB(a).change();
import 'myExtensionA.dart' show change();
void main() {
String a = "a";
a.change();
// a.reverse(); // myExtensionA에서 현재 reverse()는 import되지 않음
}
// main.dart 파일
import 'myExtensionA.dart' hide reverse;
void main() {
String a = "a";
a.change(); // change메서드는 import되었음
// a.reverse(); // 에러: MyExtensionA import되지 않았음
}
as
키워드를 이용해 임의 이름으로 지정해서, ExA(a).reverse()
로 호출 할 수 있습니다.Unnamed Extension(익명 확장 클래스)
를 사용하자!extnsion on String {
// 띄어쓰기를 제거하고 비었는지 확인함
bool get isBlank => trim.isEmpty;
}
extension ListAverage<T extends num> on List<T> {
// 숫자 리스트의 평균을 계산하는 확장 메서드
double average() {
if (this.isEmpty) return 0;
return this.reduce((value, element) => value + element) / this.length;
}
}
void main() {
List<int> intList = [1, 2, 3, 4, 5];
List<double> doubleList = [1.5, 2.5, 3.5];
print(intList.average()); // 출력: 3.0
print(doubleList.average()); // 출력: 2.5
// List<String> stringList = ['a', 'b']; // 에러: num 타입이 아님
}