다트에서는 모든 데이터가 객체이므로 함수도 객체입니다. 그리고 함수를 대입할 수 있는 객체를 함수 타입이라고 하며 Function으로 선언합니다. 다음 코드에서는 some()이라는 함수를 선언한 후 이 함수를 Function data2라고 선언한 함수 타입 객체에 대입했습니다.
// 함수 타입 선언
void some() { }
Function data2 = some;
이처럼 함수가 객체이므로 다른 객체에 대입하거나 함수의 매개변수, 반환값 등으로 사용할 수 있습니다. 다음 코드에서 testFun() 함수는 매개변수로 함수를 전달받아 함수를 반환합니다. 즉, 매개변수와 반환값이 모두 Function 타입입니다.
// 함수를 활용한 예
int plus(int no) {
return no + 10;
}
int multiply(int no) {
return no * 10;
}
Function testFun(Function argFun) {
print('argFun : ${argFun(20)}');
return multiply;
}
main(List<String> args) {
var result = testFun(plus);
print('result : ${result(20)}');
}
▶ 실행 결과
argFun : 30
result : 200
메인 함수에서 testFun() 함수를 호출할 때 plus() 함수를 전달했으며, 그 결과로 multiply()함수가 반환됩니다. 따라서 result 객체에 호출 연산자 ()를 붙여 20을 전달하면 multiply(20)처럼 호출한 것과 같습니다.
Function 타입으로 선언한 변수에는 모든 함수를 대입할 수 있습니다. 그런데 때로는 함수 타입 변수에 대입할 함수를 특정한 형태로 한정하고 싶을 때가 있습니다. 예를 들어 int 타입 매개변수를 하나 받고 결과 역시 int로 반환하는 함수만 대입할 수 있게 선언하면 다음과 같습니다.
// 함수 타입 제한
some(int f(int a)) {
f(30);
}
main(List<String> args) {
some((int a) {
return a + 20;
});
}
코드를 보면 some() 함수에 함수 타입 매개변수를 선언했습니다. int f(int a)로 선언했으므로 이 매개변수에 대입할 수있는 함수는 int 타입의 매개변수와 결괏값을 반환하는 함수여야 합니다.
익명 함수
익명 함수는 이름이 생략된 함수를 의미하며 흔히 람다 함수 라고 부릅니다.
// 익명 함수 사용 예
fun1(arg) {
return 10;
}
Function fun2 = (arg) {
return 10;
};
이 코드에서는 함수를 2개 선언했습니다. 첫 번째 함수는 이름이 fun1입니다. 그런데 두 번째 함수는 매개변수와 본문은 있지만 이름이 없으며 (arg) { } 형태로 선언했습니다. 이처럼 이름을 생략한 채 선언하는 함수를 익명 함수라고 부릅니다. 익명 함수는 이름이 없으므로 독자적으로 사용할 수 없으며 Function 타입에 대입할 함수를 정의할 때 사용합니다.
함수 타입, 익명 함수 이런 걸 많이 사용하나요?
함수를 데이터처럼 이용하게 해주는 기법은 다트뿐만 아니라 최근에 만들어진 여러 언어에서 지원하며 함수형 프로그래밍의 근간이 되기도 합니다. 플러터 API에서 제공하는 많은 함수가 매개변수를 함수 타입으로 선언하고 있습니다.
다음 코드를 보면 List 객체의 forEach() 함수를 호출하는데 매개변수에 함수를 대입했습니다. 즉, forEach() 함수의 매개변수를 함수 타입으로 선언했습니다.
// 함수 타입 매개변수 사용 예 var list = ['apples', 'bananas', 'oranges']; list.forEach((item) { print('${list.indexOf(item)}: $item'); });
다음 코드는 다트의 List 클래스에 선언된 forEach() 함수입니다. 이 함수의 매개변수가 함수 타입으로 선언되어 있습니다. 따라서 forEach() 함수를 이용할 때는 매개변수로 함수를 전달해야 하며 이때 주로 익명 함수로 선언해서 대입합니다.// forEach() 함수 정의 void forEach(void f(E element)) { for (E element in this) f(element); }
'Flutter' 카테고리의 다른 글
기타 연산자 알아보기 (0) | 2024.11.12 |
---|---|
게터와 세터 함수 (0) | 2024.11.12 |
옵셔널 위치 매개변수 (0) | 2024.11.12 |
명명된 매개변수 (0) | 2024.11.12 |
함수 선언과 호출하기 (0) | 2024.11.12 |