반응형
고차 함수 (High order function)
- 다른 함수를 인자로 받거나 함수를 반환하는 함수
함수 타입
val sum: (Int, Int) -> Int = { x, y -> x+y }
val action: () -> Unit = { println(42) }
함수 타입을 정의하려면 함수 파라미터의 타입을 괄호 안에 넣고, 그뒤에 화살표(→)를 추가한 다음, 반환 타입을 지정하면 된다.
- 함수타입을 선언할 때는 반환 타입으로 반드시 명시해야 하므로 Unit을 빼먹어서는 안 된다.
반환 타입이 널이 될 수 있는 타입
var canReturnNull: (Int, Int) -> Int? = {x, y -> null}
함수 타입 전체가 널이 될 수 있는 타입
var funOrNull: ((Int, Int) -> Int)? = null
파라미터 이름과 함수 타입
- 함수 타입에서 파라미터 이름을 지정할 수도 있다.
fun performRequest {
url: String,
callback: (code: Int, content: String) -> Unit
}
- 함수 타입에 인자 이름을 추가하면 코드 가독성이 좋아지고, IDE는 그 이름을 코드 완성에 사용할 수 있다.
인자로 받은 함수 호출
- 인자로 받은 함수를 호출하는 구문은 일반 함수를 호출하는 구문과 같다.
fun twoAndThree(operation: (Int, Int) -> Int) {
val result = operation(2,3)
}
인텔리J 아이디어 팁 디버깅할 때 람다 코드 내부를 한 단계씩 실행해볼 수 있는 스마트 스테핑을 제공한다.
자바에서 코틀린 함수 타입 사용
컴파일된 코드 안에서 함수 타입은 일반 인터페이스로 바뀐다.
즉, 함수 타입의 변수는 FunctionN 인터페이스를 구현하는 객체를 저장.
각 인터페이스에는 invoke 메서드 정의가 하나 들어있다.
invoke 메서드 본문에는 람다의 본문이 들어간다.
자바 8 람다를 넘기면 자동으로 함수 타입의 값으로 변환된다.
/* 코틀린 선언 */
fun processTheAnswer(f: (Int) -> Int) {
println(f(42))
}
/* 자바 8 */
processTheAnswer(number -> number + 1);
/* 자바 8 이전 */
processTheAnswer(
new Function1<Integer, Integer>() {
@override
public Integer invoke(Integer number) {
}
}
)
- 코틀린 표준 라이브러리에서 가져온 함수를 자바 코드에서 호출할 수 있다. (람다를 인자로 받는 확장함수)
/* 자바 */
List<String> strings = new ArrayList();
strings.add("42");
CollectionKt.forEach(strings, s -> {
return Unit.INSTANCE;
});
→ 수신 객체를 확장 함수의 첫 번째 인자로 명시적으로 넘겨야 하므로 깔끔하지는 않다.
- 반환 타입이 Unit인 함수의 경우
코틀린 Unit타입에는 값이 존재 하므로 자바에서는 그 값을 명시적으로 반환해줘야 한다.
파라미터를 함수 타입으로 선언할 때도 디폴트 값을 정할 수 있다.
- 매번 람다를 넘기게 되면 기본 동작으로도 충분한 경우 함수호출을 불편하게 만들 수 있음.
- 디폴트 값을 지정하여 해결
355p 8.4
- 디폴트 값 선언도 = 뒤에 람다를 넣으면 된다.
널이 될 수 있는 함수 타입으로 함수를 받으면 그 함수를 직접 호출할 수 없다.
- NPE발생할 가능성 있으므로 컴파일 거부
- 명시적으로 null여부 검사도 방법
fun foo(callback: (() -> Unit)?) {
if (callback != null) {
callback()
}
}
- invoke도 안전 호출 구문으로 호출할 수있다. callback?.invoke()
함수를 함수에서 반환
- 함수를 반환하려면 return 식에 람다나 멤버 참조나 함수 타입의 값을 계산하는 식 등을 넣으면 된다.
fun getShippingCostCalculator(delivery: Delivery): (Order) -> Double {
if(조건) {
return { order -> 6 + 2.1 * order.itemCount }
}
return { order -> 1.2 * order.itemCount } //함수에서 람다를 반환
}
- 상태나 다른 조건에 따라 달라질 수 있는 로직이 있을 때 유용
람다를 활용한 중복 제거
- 코드의 일부분을 복사해 붙여넣고 싶은 경우가 있다면 그 코드를 람다로 만들면 중복을 제거할 수 있다.
반응형
'코틀린 & Java > 코틀린인액션' 카테고리의 다른 글
[Kotlin] 클래스, 객체, 인터페이스에 대해 알아보자 (2) (0) | 2024.03.18 |
---|---|
인라인 함수: 람다의 부가 비용 없애기 (0) | 2023.05.23 |
delegated property 프로퍼티 접근자 로직 재활용 (0) | 2023.05.09 |
Kotlin 구조 분해 선언과 component 함수(Pair, Triple) (0) | 2023.05.09 |
Kotlin 범위 관례 인덱스로 원소 접근 Get, Set (0) | 2023.05.09 |