✅람다식 구조
- 원래 람다는 이름이 없는 함수인데 변수에 대입해서 변수처럼 사용할 수 있음
- 변수의 타입을 적어주는 것처럼 람다식의 선언 자료형을 적어준다
이때, 람다의 인자로 Int형 타입이 들어가고 return타입도 Int형이니까 (Int,Int)->Int
- 람다식 선언 자료형이 생략되었다면 람다식의 매개변수 타입은 생략될 수 없고, 반대로 람다식 선언 자료형이 명시되어있다면 매개변수 타입은 생략될 수 있음
- 람다식의 처리 내용이 여러줄일 경우는 마지막 표현식이 반환됨!
✅람다가 리턴하는 값과 자료형의 생략
- 위에서 람다식 내용 여러줄이면 항상 마지막 표현식이 반환된다는거 주의!!
- 자료형을 생략할 수 있는 방법은 3개다. 선언자료형과 매개변수 자료형 중 반드시 하나에는 자료형을 명시해줘야함. 두군데 모두 생략하면 에러다
- 선언 자료형에서, 반환되는 리턴타입이 없으면, 즉 반환되는 자료형이 없으면 Unit으로 표현한다
- 선언자료형에서 인자가 없는걸 표현할 땐 () 로 표현하고 매개변수도 작성 안하고 그냥 로직만 써준다
- 인자에 람다를 사용한 고차함수의 예시다 여기서 sum:(Int,Int)->Int 는 sum이라는 변수의 선언 자료형이 람다이기 때문에 람다를 인자로 받고있고 return sum(a,b) 에서 람다식을 변수에 대입해서 사용할 수 있기때문에 가능한 것이다.
✅변수 이름으로 호출하기vs()로 호출하기
✔()로 호출하기
- Lambda를 인자없이 Lambda()로 호출할떄는 리턴값인 true가 반환됨
✔변수 이름으로 호출하기
- 인자가 없는 람다식을 담고 있는 변수를 이름으로 호출할 경우, 리턴값이 아니라 람다식의 코드블록이 그대로 멱살잡혀 끌려간다 생각하면 된다
- 위에처럼 ()로 호출하는 경우와 차이가 있고 이 두 경우를 잘 이용하면 상황에 맞춰 즉시 실행할 필요가 없는 코드를 작성하는 경우 이름에 의한 호출 방법을 통해 필요할 때만 람다식 함수가 작동하도록 만들 수 있다.
✅람다가 아닌 함수를 람다식처럼 인자로 받기(참조)
- sum이라는 함수는 람다식이 아닌데 funcParam이라는 함수의 람다식 선언자료형으로 표기된 3번째 인자로 넣으려고하면 오류가 발생한다. 그 이유는 sum은 람다식으로 작성된 함수가 아니기 때문이다
- 람다식 함수가 아닌 함수를 함수의 인자로 사용할 수 있는 방법은, ::sum 의 참조방식으로 호출하면 람다식 형태로 호출받아서 매개변수로 사용할 수 있게 된다
- 일반함수를 참조형으로 사용해서 람다식처럼 사용하면 다방면있게 활용가능
✅매개변수 개수에 따라 람다식을 구성하는 방법
✔매개변수가 없는 경우
✔매개변수가 한 개인 경우
✔매개변수가 두 개인 경우
- 매개변수가 두개인 경우에는 it으로 대체하거나 생략할 수 없음
✔매개변수를 생략하는 경우
- 매개변수에 디폴트 값이 있다거나 값을 생략하는 경우
_
로 표시
✔일반 매개변수와 람다식 매개변수를 같이 사용
- 매개변수가 여러개 있고 마지막 매개변수가 람다식 선언형일때 인자로 전달하는 경우 마지막 인자인 람다식의 {}를 () 밖으로 빼낼 수 있음 이건 규칙이다.
- 그렇다면 매개변수에 람다식 선언형이 여러개 있으면? 무조권 마지막 인자인 람다만 소괄호 () 밖으로 빼낼 수 있고 나머진 안됨!
✅Sample code
package Lambda
fun main() {
val res1 = sum(3, 2)
val res2 = mul(sum(3, 2), 5)
val multi: (Int, Int) -> Int = { a: Int, b: Int -> a * b }
val result: Int
result = multi(10, 20)
val test1: (Int, Int) -> Int = { a: Int, b: Int -> a * b }
val test2 = { a: Int, b: Int -> a * b }
val test3: (Int, Int) -> Int = { a, b -> a * b }
val test4: () -> Unit = { println("Hello") }
val test5: (Int) -> Int = { a -> a * a }
println(test4)
println(test4())
val test6 = { println("Hello") }
val test7 = { a: Int, b: Int -> a * b }
val test8 = { a: Int, b: Int ->
println("첫번째줄")
println("두번째줄")
println("세번째줄")
}
fun test9(minus: (Int, Int) -> Int, b: Int, c: Int): Int {
return minus(b, c)
}
test9({ a: Int, b: Int -> a - b }, 20, 10)
val test10 = callByValue(Lambda())
println(test10)
val test11 = callByValue2(otherLambda)
println(test11)
order(::sum11, 11, 12)
noParam({ "Hi" })
noParam() { "Hi" }
noParam { "Hi" }
oneParam({ a -> a })
oneParam() { a -> a }
oneParam { a -> a }
oneParam { "a+$it" }
moreParam { a, g -> a + g }
withArgs("a", "b", { a, b -> a + b })
withArgs("a", "b") { a, b -> a + b }
}
fun withArgs(a: String, b: String, out: (String, String) -> String) {
println(out(a, b))
}
fun noParam(out: () -> String) {
println(out())
}
fun moreParam(out: (String, String) -> String) {
println(out("", ""))
}
fun oneParam(out: (String) -> String) {
println(out(""))
}
fun order(sum: (Int, Int) -> Int, a: Int, b: Int): Int {
return sum(a, b)
}
fun sum11(a: Int, b: Int): Int {
return a + b
}
fun callByValue2(b: () -> Boolean): Boolean {
println("callByValue2")
return b()
}
val otherLambda: () -> Boolean = {
println("otherLambda")
true
}
fun callByValue(b: Boolean): Boolean {
println("callByValue")
return b
}
val Lambda: () -> Boolean = {
println("Lambda")
true
}
fun sum(a: Int, b: Int) = a + b
fun mul(a: Int, b: Int) = a * b
fun funFunc(): Int {
return sum(2, 2)
}
참고
Do it! 코틀린 프로그래밍- 고차함수와 람다함수