package chap03.section3.funcargs
fun main() {
val res1 = sum(3, 2) // 일반 인자
val res2 = mul(sum(3, 3), 3) // 인자에 함수를 사용
println("res: $res1, res2: $res2")
}
fun sum(a: Int, b: Int) = a + b
fun mul(a: Int, b: Int) = a * b
package chap03.section3.funcargs
fun main() {
println("funcFunc: ${funcFunc()}")
}
fun sum(a: Int, b: Int) = a + b
fun funcFunc() : Int { // 함수의 반환값으로 함수 사용
return sum(2, 2)
}
package chap03.section3
fun main() {
var result: Int
val multi = {x: Int, y: Int -> x * y} // 일반 변수에 람다식 할당
result = multi(10, 20) // 람다식 할당된 변수는 함수처럼 사용 가능
// 변수이지만 두 개의 인자가 필요하다.
println(result)
}

val multi2: (Int, Int) -> Int = {x: Int, y: Int ->
println("x + y")
x + y // 제일 마지막 표현식이 반환됨
}
📌 어떤 결과가 실행될까?
fun main() {
val result: Int
val multi = {x: Int, y: Int ->
println("x * y")
x // 마지막 표현식이 반환되기 때문에 x를 작성해도 아무런 문제가 발생하지 않음
x + y // 반환식이 2줄 이상일 경우 마지막 표현식이 반환됨
}
// multi는 변수의 이름이고, 실제 람다식은 이름이 없는 익명 함수이다.
result = multi(10, 20)
println(result)
}
🔑 실행결과
x + y
200
val multi: (Int, Int) -> Int = {x: Int, y: Int -> x * y} // 생략되지 않은 전체 표현
val multi = {x: Int, y: Int -> x * y} // 선언 자료형 생략
val multi: (Int, Int) -> Int = {x, y -> x * y} // 람다식 매개변수 자료형의 생략
val multi = {x, y -> x * y} // 에러 발생! 자료형 추론이 가능하지 않음
// 반환 자료형이 없기 때문에 소괄호()에 아무것도 쓰여있지 않다.
// 전달한 인자가 없기 때문에 화살표 또한 사라진다.
val greet: () -> Unit = { println("Hello World") }
// 매개변수가 하나 있을 때
val square: (Int) -> Int = { x -> x * x }
📌 주의하기
val greet: () -> Unit = { println("Hello") }
println(greet)
greet()
🔑 실행결과
// greet가 가지고 있는 Hello가 출력되는 게 아니라 람다식 자체가 나온다.
// 인자가 없고 반환 데이터의 자료형이 Unit라는 람다식이 들어있음을 코틀린이 알려준다.
() -> kotlin.Unit
Hello
// greet 변수에 들어있는 처리문만 수행한 다음에 아무것도 반환하지 않고 여기서 끝난다.
val nestedLambda: () -> () -> Unit = { { println("nested") } }
📌 주의하기
val nestedLambda: () -> () -> Unit = { { println("World") } }
nestedLambda() // 함수 안에 또다른 함수가 있는 것으로 생각해야 한다.
nestedLambda()() // 따라서 호출하기 위해서는 괄호는 두 번 입력해주어야 한다.
🔑 실행 결과
World!
val greet = { println("Hello World") } // 추론 가능
val square = { x: Int -> x * x } // 선언 부분을 생략하려면 x의 자료형을 명시해야 함
val nestedLambda = { { println("nested") } } // 추론 가능
fun main() {
var result: Int
result = highOrder({ x, y -> x + y}, 10, 20)
println(result)
}
// 매개변수의 자료형 자체가 람다식 형태
fun highOrder(sum: (Int, Int) -> Int, a: Int, b: Int): Int {
return sum(a, b)
}
🔑 실행 결과
30

fun main() {
val result = callByValue(lambda()) // 람다식 함수를 호출
println(result)
}
fun callByValue(b: Boolean): Boolean { // 일반 변수 자료형으로 선언된 매개변수
println("callByValue function")
return b
}
val lambda: () -> Boolean = { // 변수 lambda
println("lambda function") // 람다 표현식이 두 줄
true // 마지막 표현식 문장의 결과가 반환
}

🔑 실행 결과
lambda function
callByValue function
true
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
🔥 위 두 개의 코드 차이점 잘 기억하기!!!
fun sum(x: Int, y: Int) = x + y // 람다식이 아니다.
funcParam(3, 2, sum) // 오류! sum은 람다식이 아니다!
fun funcParam(a: Int, b: Int, c: (Int, Int) -> Int): Int {
return c(a, b)
}
// sum이 람다식이 아니기 때문에 그대로 호출하게 되면 오류가 발생한다.
// 따라서 sum을 람다식처럼 호출시키기 위해 참조 방식으로 ::를 사용한다.
funcParam(3, 2, ::sum)
fun main() {
// 1. 인자와 반환값이 있는 함수
val res1 = funcParam(3, 2, ::sum)
println(res1)
// 2. 인자가 없는 함수
hello(::text) // 반환값이 없음
// 3. 일반 변수에 값처럼 할당
val likeLambda = ::sum // likeLamvda를 함수처럼 사용 가능
println(likeLambda(6, 6))
}
fun sum(a: Int, b: Int) = a + b
fun text(a: String, b: String) = "Hi! $a $b"
// 람다식 형태로 되어있는 매개변수 c
fun funcParam(a: Int, b: Int, c: (Int, Int) -> Int): Int {
return c(a, b)
}
fun hello(body: (String, String) -> String): Unit {
println(body("Hello", "World"))
}
fun main() {
// 매개변수 없는 람다식 함수
noParam({ "Hello World" })
noParam { "Hello World" } // 위와 동일 결과, 소괄호 생략 가능
}
// 매개변수가 없는 람다식 함수가 noParam 함수의 매개변수 out으로 지정됨
fun noParam(out: () -> String) = println(out())
🔑 실행 결과
Hello World!
Hello World!
fun main() {
// 매개변수가 없는 람다식 함수
// 매개변수가 하나 있는 람다식 함수
oneParam( { a -> "Hello World! $a" } )
oneParam { a -> "Hello World! $a" } ) // 소괄호 생략 가능
oneParam {"Hello World! $it } // 위와 동일 결과, it으로 대체 가능
}
// 매개변수가 하나 있는 람다식 함수가 oneParam함수의 매개변수 out으로 지정됨
fun oneParam(out: (String) -> String) {
println(out("OneParam"))
}
인자가 하나만 있는 경우 인자와 화살표를 생략하고 처리구문은 it으로 대체할 수 있다. it이 받아드리고자 하는 인자 하나를 가리키고있다. 그렇기에 인자가 하나인 경우 조금 더 편리하게 사용가능하다.
매개변수가 두 개 이상인 경우
fun main() {
moreParam { a, b -> "Hello World! $a $b"} // 매개변수명 생략 불가
}
fun moreParam(out: (String, String) -> String) {
println(out("OneParam", "TwoParams"))
}

// 언더바(_)를 통해 비워둔다.
moreParam { _, b -> "Hello World! $b"} // 첫 번째 문자열은 사용하지 않고 생략
fun main() {
// 인자와 함께 사용하는 경우
withArgs("Arg1", "Args2", { a, b -> "Hello World! $a $b" })
// withArgs()의 마지막 인자가 람다식인 경우 소괄호 바깥으로 분리 가능
withArgs("Args1", "Args2) { a, b -> "Hello World! $a $b" }
}
// withArgs 함수는 일반 매개변수 2개를 포함, 람다식 함수를 마지막 매개변수로 가짐
fun withArgs(a: String, b: String, out: (String, String) -> String) {
println(out(a, b))
}
🔥 마지막에 람다식이 구성되어 있다면, 바깥으로 빼낼 수 있다.
fun main() {
twoLambda( { a, b -> "First $a $b" }, {"Second $it"} )
twoLambda( { a, b -> "First $a $b" }) {"Second $it"} // 위와 동일
}
// 매개변수로서 람다식이 두 개
fun twoLambda(first: (String, String) -> String, second: (String) -> String) {
println(first("OneParam", "TwoParam"))
println(second("OneParam"))
}