코틀린 심화문법 - 람다, 고차함수
코틀린 심화문법에서 이미 설명하긴 했지만, 설명이 난해했던 것 같아서 추가로 작성한다.
람다 함수
- 익명 함수 정의 기법
- 반환값은 본문의 마지막 표현식
{ 매개변수 -> 함수 본문 }
일반함수
fun sum(no1: Int, no2: Int): Int {
return no1 + no2
}
람다함수
{ no1: Int, no2: Int -> no1 + no2 }
람다함수는 fun 키워드도 없고 함수 이름도 없다.
람다함수는 이름이 없으므로 함수명으로 호출할 수 없다. 보통은 그래서 변수에 대입해 사용한다.
val sum = { no1: Int, no2: Int -> no1 + no2 }
sum(10, 20)
하지만 꼭 변수에 대입할 필욘 없다.
{ no1: Int, no2: Int -> no1 + no2 } (10, 20)
정의와 동시에 호출한 경우이다.
매개변수 없는 람다
{ -> println("call") }
이렇게 해도 되고
{ println("call") }
이렇게 해도 된다.
람다표현식 1
매개변수가 1개인 일반적인 람다
val some = { no: Int -> println(no) }
sime(10)
람다표현식 2
근데 매개변수가 1개일땐 it으로 참조가 가능하다.
val some: (Int) -> Unit = { println(it) }
some(10)
그거나 그거나 비슷함 사실. 근데 이 방법을 쓰는 이유는 따로 있다. 아래에서 다룬다.
람다표현식 1
매개변수가 두 개 이상일 때 부터는, it으로 참조가 불가능하다.
val some = { no1: Int, no2: Int -> println(no1 + no2) }
some(10, 20)
따라서 이렇게 이용해줘야 한다. 그럼 람다표현식1만 사용하면되지, 람다표현식2는 왜 사용하는걸까?
거의 다 왔다. 예시를 아래에서 다룬다.
잘못된 사용방식
val some = { println(it) } // X
이건 타입을 식별할 수 없어서 오류가 난다.
it은 해당 매개변수의 타입을 식별할 수 있을 때만 가능하다.
따라서 매개변수가 하나일 때는
이미 타입이 정해져 있고, 구현체를 구현할 때 간편하게 활용되는 것이다.
interface OnClickListener {
abstract fun onClick(v: View!): Unit
}
고차 함수
일반적으로 함수의 매개변수나 반환값은 데이터다.
함수를 매개변수나 반환값으로 이용하는 함수를 고차함수라고 한다.
고차함수가 가능한건, 함수형 프로그래밍에서 함수를 변수에 대입하는게 가능하기 때문이다.
fun high(arg: (Int) -> Boolean): () -> String {
val result = if(arg(10)) {
"valid"
} else {
"invalid"
}
return { "high result : $result" }
}
fun main() {
val result = high( {no -> no > 0})
println(result())
}
main 함수에서 high의 인자로 아래와 같은 람다를 넘겨줬다.
{ no -> no > 0 }
이 람다가, high 함수 정의문의 (Int) -> Boolean 의 인자가 된다.
val arg: (Int) -> Boolean = { no -> no > 0 }
이 정의된 것이다.
+ 참고로 람다를 이렇게 정의할 때, 위와같이 리턴타입은 괄호로 감싸지 않아도 되지만 인자 부분은 항상 () 괄호로 감싸야 한다. 인자는 여러개일 수 있지만 리턴은 항상 하나기 때문.
말했지만 위 람다를 이렇게 정의해도 동일하다.
val arg = { no: Int -> no > 0 }
그리고 이 high 함수의 리턴타입도 람다다. 인자는 없고 리턴은 String인 람다.
() -> String { ... }
이것이 result 변수에 담기게 되고, 따라서 이 함수를 호출할 때
result() 이렇게 호출하여 String을 리턴하는 것이다.