빠르게 살펴보기
함수 타입의 리터럴인 람다식의 완전한 문법적 형태는 다음과 같습니다.
val sum = { x: Int, y: Int -> x + y}
람다식은 항상 중괄호{ }로 묶여 있습니다. 완전한 문법적 형태(full syntactic form)에서는 중괄호 내에 파라미터를 선언하고 생략 가능한 type annotation을 가집니다. body는 -> 뒤에 옵니다. 만약에 유추된 람다의 리턴 타입이 Unit이 아닌 경우에는 람다 body 내에 마지막 표현식이 리턴 값으로 처리됩니다.
즉, 위의 예에서 모든 생략 가능한 annotation을 생략하지 않은 형태는 다음과 같습니다.
val sum: (Int, Int) -> Int = { x, y -> x + y }
type annotation은 (Int, Int)이며 리턴 타입은 Int입니다. 만약 리턴 타입이 생략되었다면 -> 뒤에 오는 body인 x + y의 타입으로 처리되겠죠.
결국 함수이기 때문에 함수명(파라미터)으로 사용할 수 있습니다.
fun main(args: Array<String>) {
val sumOptional = { x: Int, y: Int -> x + y}
val sumFull: (Int, Int) -> Int = { x, y -> x + y }
println("sumOptional(10, 15) = ${sumOptional(10, 15)}")
println("sumFull(10, 20) = ${sumFull(10, 20)}")
}
sumOptional(10, 15) = 25
sumFull(10, 20) = 30
람다식은 하나의 파라미터를 가지는 것이 일반적입니다. 따라서 코틀린이 파라미터를 사용중인 것을 알 수 있으면 파라미터 선언을 해주지 않아도 되고 it이라는 키워드로 암시적으로 선언할 수 있습니다.
fun main(args: Array<String>) {
val add: (Int) -> Int = { it + 1 }
println("add(10) = ${add(10)}")
}
add(10) = 11
qualified return syntax를 사용하여 람다로부터 값을 명시적으로 리턴할 수 있습니다. 그렇게 하지 않으면 마지막 표현식의 값이 암시적으로 리턴됩니다. 따라서 다음의 isPositive와 isPositiveTest는 같습니다.
fun main(args: Array<String>) {
val isPositive: (Int) -> Boolean = {
val isPositive = it > 0
isPositive
}
val isPositiveTest: (Int) -> Boolean = number@ {
val isPositive = it > 0
return@number isPositive
}
println("isPositive(10) = ${isPositive(10)}")
println("isPositiveTest(-10) = ${isPositiveTest(-10)}")
}
isPositive(10) = true
isPositiveTest(-10) = false