코틀린 람다 (Kotlin Lambdas)

저뉼(스님?)·2023년 11월 17일
0

나만의 설명

목록 보기
8/11

Kotlin DSL을 대충 이해한 채로 사용하다가 제대로 이해해 보려던 중 Lambda부터 한번 정리해야겠다 싶었다.

언어별 람다 (함수 정의)

언어별로 람다를 사용해서 간단한 함수를 만들어 봤어요.
(두 개의 정수를 더한 결과를 반환하는 sum 함수)

TypeScript

const sum = (a: number, b: number) => a + b;
sum(2, 5);

Python

sum = lambda a, b : a + b
sum(2, 5)

C#

Func<int, int, int> sum = (a, b) => a + b;
sum(2, 5);

Java

BiFunction<Integer, Integer, Integer> sum = (a, b) -> a + b;
sum.apply(2, 5);

그리고
Kotlin

val sum = { a: Int, b: Int -> a + b }
sum(2, 5)

다 비슷비슷하네요.

그럼,
람다란 함수를 간략하게 정의할 수 있는 수단인가?
틀린 말은 아닌데..

더 중요한 건 지금부터에요.

코틀린 람다 (함수 전달)

"Kotlin functions are first-class"

함수 parameter의 argument로 Int, String과 같은 값뿐만 아니라 함수를 전달할 수도 있어요.
(함수를 전달받는 함수를 high-order function이라고 함)

fun higherOrderFunction(functionTypeParam: (Int, Int) -> Int) {}

함수를 전달받을 수 있는 high-order function을 하나 만들었어요.
parameter는 두 개의 Int를 받고 Int를 반환하는 함수에요.

parameter 타입이 아까 위에서 만들었던 sum() 함수의 타입과 같아서 sum 함수를 전달할 수 있을 것 같네요. 전달해 보겠습니다.

val sum = { a: Int, b: Int -> a + b }
higherOrderFunction(functionTypeParam = sum)

(참고로, 코틀린에서는 sum 함수를 fun 키워드를 사용하여 정의했다면 위처럼 전달 불가)

여기까지만으로도 문법적 오류 없이 함수를 잘 전달했어요.
그렇지만 가독성을 해치지 않는 선에서 간결하게 표현할수록 더 좋지 않을까요?

간략화 과정

위에서 보았던 sum() 함수를 전달하며 higherOrderFunction() 함수를 호출하는 구문을 간략하게 만들어 가 보겠습니다.

+1 강화!
중간 역할을 하는 sum이라는 변수를 없애면서 좀 더 간략하게.

higherOrderFunction(functionTypeParam = { a: Int, b: Int -> a + b })

+2 강화!
이 경우, a, b의 타입을 추론할 수 있기 때문에 아래와 같이 타입을 명시한 부분(: Int)을 생략할 수 있어요.

higherOrderFunction(functionTypeParam = { a, b -> a + b })

+3 강화!
이제, parameter 이름을 명시한 부분도 생략해 봅시다.

higherOrderFunction({ a: Int, b: Int -> a + b })

+4 강화!
마지막으로, 괄호()마저 생략할 수 있어요.

higherOrderFunction { a: Int, b: Int -> a + b }

마지막 형태만 딱 놓고 보면 좀 헷갈릴 수도 있을 텐데,
우린 방금까지 higherOrderFunction()이라는 함수에게 '두 Int를 받아 그 합을 반환하는 함수'를 전달한 거에요.
(사실 이 마지막 형태 때문에 이 글을 작성하게 된 것이랍니다.)

이렇듯 람다를 이용하면 간결하게 함수에게 함수를 전달할 수 있어요.
(또한, Kotlin DSL로 확장)

핵심적인 건 다 끝났고
자잘한 것들만 코드로 간단하게 살펴 봅시다.

다양한 케이스

람다로 만든 함수가 여러 줄일 때

val sum = { a: Int, b: Int ->  
    println("a: $a")  
    println("b: $b")  

	// 마지막 줄에 있으면 return 키워드 없이 return됨
    a + b  
}

high-order function에 parameter가 함수 외에 더 있을 때

함수를 마지막에 받는 경우

fun higherOrderFunction(s: String, functionTypeParam: (Int, Int) -> Int) {}
// higherOrderFunction("두 정수의 합", { a, b -> a + b })
higherOrderFunction("두 정수의 합") { a, b -> a + b } // 소괄호 바깥에 람다

함수를 마지막에 받지 않는 경우

fun higherOrderFunction(functionTypeParam: (Int, Int) -> Int, s: String) {}
higherOrderFunction({ a, b -> a + b }, "두 정수의 합") // 소괄호 안에 람다

high-order function의 parameter인 함수의 parameter가 하나일 때

fun higherOrderFunction(functionTypeParam: (Int) -> Int) {}
higherOrderFunction { num -> num * num }
higherOrderFunction { it * it }

higherOrderFunction()에게 '정수 하나를 받아 그 제곱을 반환하는 함수'를 전달한 것

0개의 댓글