package chap04.section1
fun main() {
val result: Int
// 일반 변수에 람다식 할당
//val multi = { a: Int, b: Int -> a * b }
val multi: (a: Int, b: Int) -> Int = { a, b -> a * b }
// 람다식이 할당된 변수는 함수처럼 사용 가능
result = multi(3, 5)
println(result)
}
package chap04.section1
fun main() {
val multi: (Int, Int) -> Int = { x: Int, y: Int -> x * y }
val multi1 = { x: Int, y: Int -> x * y } // 선언 자료형 생략
val multi2: (Int, Int) -> Int = { x, y -> x * y } // 람다식 매개변수 자료형 생략
val multi3 = { x, y -> x * y } // error
}
코틀린에서 값에 의한 호출은 함수가 인자로 전달될 경우, 람다식 함수는 값으로 처리되어 그 즉시 함수가 수행된 후 결과를 반환한다.
package chap04.section2
fun main() {
val result = callByValue(lambda()) // 람다 함수 호출
println(result)
}
fun callByValue(b: Boolean): Boolean { // 일반 변수 타입으로 선언된 매개변수
println("callByValue function")
return b
}
val lambda: () -> Boolean = { // 람다 표현식이 2줄 이상일 때는
println("lambda function")
true// 마지막 표현식 반환
}
lambda function
callByValue function
true
그렇다면, 람다 함수가 인자로 전달되는 즉시 실행되는 것이 아니라, 실제로 그 함수가 사용될 때 실행되게 하려면 어떻게 해야 할까? 람다 함수의 이름을 인자로 넣어서 사용하면, 람다식 자체가 매개변수에 복사되고 해당 함수가 사용되기 전까지는 함수가 실행되지 않는다. 람다 함수가 호출되어 사용될 때 비로소 그 함수의 내용이 실행된다! 이것을 잘 이용하면, 즉시 실행할 필요가 없는 코드를 작성하는 경우, 이름에 의한 호출 방법으로 필요할 때만 람다 함수가 작동하게 만들 수 있다!
package chap04.section2
fun main() {
val result = callByName(otherLambda) // 람다식 이름으로 호출
println(result)
}
fun callByName(b: () -> Boolean): Boolean { // 람다 함수 타입으로 선언된 매개변수
println("callByName function")
return b()
}
val otherLambda: () -> Boolean = {
println("otherLambda function")
true
}
callByName function
otherLambda function
true
package chap04.section2
fun sum(x: Int, y: Int) = x + y
fun funcParam(a: Int, b: Int, c: (Int, Int) -> Int): Int {
return c(a, b)
}
fun main() {
//funcParam(3, 2, sum) // error (sum은 람다식이 아님)
println(funcParam(3, 2, ::sum)) // 함수 참조에 의한 호출
}
5
package chap04.section2
fun main() {
// 1. 인자와 리턴값이 있는 함수
val res1 = funcParam(3, 2, ::sum)
println(res1)
// 2. 인자가 없는 함수
hello(::text) // 다른 함수 참조에 의한 호출 (hello 자체는 리턴값 없음)
// 3. 일반 변수에 함수를 값처럼 할당하는 경우
val likeLambda = ::sum
println(likeLambda(6, 6))
}
fun sum(a: Int, b: Int) = a + b
fun funcParam(a: Int, b: Int, c: (Int, Int) -> Int): Int {
return c(a, b)
}
fun text(a: String, b: String) = "Hi! $a $b"
fun hello(body: (String, String) -> String): Unit {
println(body("Hello", "World"))
}
5
Hi! Hello World
12
package chap04.section2
// 매개변수가 없는 람다 함수 out
fun noParam(out: () -> String) = println(out())
// 매개변수가 1개인 람다 함수 out
fun oneParam(out: (String) -> String) {
println(out("OneParam"))
}
// 매개변수가 2개인 람다 함수 out
fun moreParam(out: (String, String) -> String) {
println(out("OneParam", "TwoParam"))
}
fun main() {
noParam({"Hello World!"})
noParam{"Hello World!"} // 소괄호 생략
oneParam({ a -> "Hello World! $a" })
oneParam{ a -> "Hello World! $a" } // 소괄호 생략
oneParam { "Hello World! $it" } // 매개변수가 1개일 때는 화살표를 생략하고 it로 대체 가능!
moreParam { a, b -> "Hello World! $a $b" } // 매개변수명 생략 불가
}
Hello World!
Hello World!
Hello World! OneParam
Hello World! OneParam
Hello World! OneParam
Hello World! OneParam TwoParam
package chap04.section2
fun moreParam(out: (String, String) -> String) {
println(out("OneParam", "TwoParam"))
}
fun main() {
// 첫번째 문자열은 사용하지 않고 생략하는 경우
moreParam { _, b -> "Hello World! $b" }
}
Hello World! TwoParam
package chap04.section2
fun withArgs(a: String, b: String, out: (String, String) -> String){
println(out(a, b))
}
fun main() {
// 일반 매개변수와 람다식을 같이 사용하는 경우
withArgs("Arg1", "Arg2", { a, b -> "Hello World! $a $b "})
// 마지막 인자가 람다식이면 소괄호 바깥으로 뺄 수 있음.
withArgs("Arg1", "Arg2") { a, b -> "Hello World! $a $b " }
}
Hello World! Arg1 Arg2
Hello World! Arg1 Arg2
package chap04.section2
fun twoLambda(first: (String, String) -> String, second: (String) -> String){
println(first("OneParam", "TwoParam"))
println(second("OneParam"))
}
fun main() {
// 두 개의 람다식을 가진 함수
twoLambda({a, b -> "First $a $b"}, {"Second $it"})
// 마지막 인자로 사용된 람다식은 소괄호 바깥으로 분리
twoLambda({a, b -> "First $a $b"}) {"Second $it"}
}
First OneParam TwoParam
Second OneParam
First OneParam TwoParam
Second OneParam