반응형
8장. 고차함수 : 파라미터와 반환 값으로 람다 사용
- 고차 함수
- 람다를 인자로 받거나 반환하는 함수
- 고차함수를 사용해서 코드를 더 간결하게, 중복을 없애고 더 나은 추상화를 하자
- 인라인 함수
- 람다를 사용함에 따라 발생할 수 있는 성능상 부가비용을 없앰
- 람다 안에서 더 유연하게 흐름을 제어할 수 있다
8.1 고차 함수 정의
- 고차함수 : 다른 함수를 인자로 받거나 함수를 반환하는 함수
- 코틀린에서는 람다나 함수 참조를 사요해 함수를 값으로 표현할 수 있다
- ex) filter 함수
list.filter {x > 0}
- 술어 함수를 인자로 받으므로 고차함수
8.1.1 함수 타입
val sum = {x : Int, y : Int -> x+y}
val sum : (Int, Int) -> Int = {x, y -> x+y}
// Int 파라미터 두개를 받아서 Int 값 반환하는 함수
val action = {println(42)}
val action: () -> Unit = {println(42)}
// 아무 인자도 받지 않고 리턴값이 없는(Unit) 함수
- 함수 타입 정의는
함수 파라미터 타입 -> 함수 반환 타임
형식으로 지정 - 함수 타입을 정의하면 lambda 안에서 parameter 타입 지정해줄 필요 없다
// 반환값이 널이 될 수 있는 경우
var canReturNull : (Int, Int) -> Int? = {x,y => null}
// 함수 자체가 널이 될 수 있는 경우
var funOrNull : ((Int, Int) -> Int)? = null
- 349p 예제 {} 람다식 안 => 화살표의 정체 ?
8.1.2 인자로 받은 함수 호출
fun twoAndThree(operation: (Int, Int) -> Int){
val result = operation(2,3)
println("The result is $result")
}
twoAndThree{a,b -> a+b} // 5
twoAndThree{a,b -> a*b} // 6
- 두 int parameter를 받아서 int 값을 반환하는 함수 타입의 파라미터를 받는 twoAndThree 함수를 정의
- 두 int를 더하는 람다식, 두 int를 곱하는 람다식을 "operation" parameter로 넣어주어 실행
8.1.3 자바에서 코틀린 함수 타입 사용
- 컴파일된 코드 안에서 함수 타입은 일반 인터페이스로 바뀐다
- 함수타입 -> FunctionN 인터페이스를 구현한 객체가 된다
- ex) Function0<R>,Funcion1<P1, R>
- p : paramter, r : return
- 각 인터페이스의 invoke 메소드로 함수를 실행할 수 있다
// kotlin
fun processTheAnswer(f : (Int) -> Int){
println(f(42))
}
// java8
processTheAnswer(number -> number + 1);
// java8 이전
processTheAnswer(
new Function1<Integer, Integer>(){
@Override
public Integer invoke(Integer number){
--
}
}
)
- java8 이전의 자바에서는 필요한 FunctionN 인터페이스의 invoke 메소드를 구현해야 한다
- 자바에서 코틀린 표준 라이브러리가 제공하는 고차함수를 호출할 수도 있다
- 반환타입이 Unit이면 명시적으로 Unit.INSTANCE를 반환해야 한다
8.1.4 디폴트 값을 지정한 함수 타입 파라미터나 널이 될 수 있는 함수 타입 파라미터
fun <T> Collection<T>.joinToString(
separator : String = ", ",
transform : (T) -> String = {it.toString() }
): String{
val result = StringBuilder(prefix)
for (element in this){
result.append(transform(element))
}
}
joinToString{it.toLowerCase()}
- joinToString 을 할때 transform 함수의 디폴트 값을 지정할 수 있다
- joinToString을 호출할 때 다른 람다식을 넣어줄 수도 있다
- 널이 될 수 있는 함수 타입 paramter
- 널이 될 수 있는 함수 타입으로 함수를 받으면 그 함수를 직접 호출할 수 없다
- NPE 가능성
- 널이 될 수 있는 함수 타입으로 함수를 받으면 그 함수를 직접 호출할 수 없다
fun foo(callback : (() -> Unit)?){
if(callback != null){
callback()
}
}
- 위와 같이 명시적으로 null 여부 검사하면 호출 가능
8.1.5 함수를 함수에서 반환
- ex) 사용자가 선택한 배송 수단에 따라 배송비를 계산하는 함수를 다르게 반환
8.1.6 람다를 활용한 중복 제거
- ex) 운영체제 별 사이트 방문 데이터 분석하기
- os 별, path 별 하드코딩 하여 분석할 수 있다
- 중복된 코드 부분을 람다로 만들면 중복을 제거할 수 있다
반응형
'Languages' 카테고리의 다른 글
kotlin 고차함수에서의 흐름제어 (return, @label) (0) | 2020.05.27 |
---|---|
kotlin의 inline 함수 (고차함수, synchronized) (0) | 2020.05.26 |
kotlin의 구조분해 선언과 component 함수 (0) | 2020.05.18 |
kotlin 의 비교 연산자 오버로딩 (equals, compareTo) (0) | 2020.05.18 |
kotlin 산술 연산자 오버로딩 (+, - *) (0) | 2020.05.18 |