프로그래밍Kotlin 개발자

Kotlin에서 고차원 함수와 람다 표현식을 어떻게 구현하나요? 함수의 전달과 반환에 대한 세부 사항, 문법의 특징, 주요 제한 사항에 대해 설명하고 코드 예제를 제공하세요.

Hintsage AI 어시스턴트로 면접 통과

답변.

고차원 함수는 다른 함수를 매개변수로 받거나 반환하는 함수입니다. Kotlin은 람다 표현식을 사용하여 동작을 값으로 편리하게 전달합니다.

선언 예시:

fun operateOnNumbers(a: Int, b: Int, operation: (Int, Int) -> Int): Int { return operation(a, b) } val sum = operateOnNumbers(3, 2) { x, y -> x + y } // sum = 5

함수 전달:

  • 함수는 람다 표현식뿐만 아니라 참조 형식으로도 전달할 수 있습니다: :
fun multiply(x: Int, y: Int) = x * y operateOnNumbers(2, 3, ::multiply)

함수 반환:

fun makeMultiplier(factor: Int): (Int) -> Int = { x -> x * factor } val triple = makeMultiplier(3) val result = triple(10) // 30

특징:

  • 람다는 하나의 비명명 매개변수(it)를 가질 수 있습니다.
  • 함수에 명명된 매개변수를 전달할 수 있지만, 타입이 제대로 유추되지 않을 경우 명시적으로 타입을 지정해야 합니다.
  • 람다 표현식은 객체(익명 클래스)이며, 많은 호출이 있는 뜨거운 루프에서 성능에 영향을 미칩니다(이를 해결하기 위해 inline 함수를 사용합니다).
  • 변수를 캡처하는 람다에는 클로저(closure)가 사용됩니다.

헷갈릴 수 있는 질문.

(Int, Int) -> Int 타입 선언과 Function2<Int, Int, Int> 타입 사용의 차이는 무엇인가요?

답변: (Int, Int) -> Int 문법은 Function2<Int, Int, Int> 인터페이스에 대한 더 "아름다운" 선언(구문적 설탕)입니다. 실제로 두 가지 모두 완전히 상호 교환 가능합니다.

val f1: (Int, Int) -> Int = { x, y -> x + y } val f2: Function2<Int, Int, Int> = { x, y -> x + y }

하지만 첫 번째 방법은 가독성 때문에 일반적으로 선호됩니다.

주제에 대한 세부 사항을 모르는 것 때문에 실제 오류의 예.


이야기

대규모 이벤트 처리 시스템에서 inline 함수를 사용하지 않고 루프 내에 수십 개의 람다 표현식이 생성되었습니다. 이로 인해 GC에 높은 부하가 걸리고 성능 저하가 발생했습니다. 각 호출마다 별도의 익명 함수 객체가 생성되었기 때문입니다.


이야기

다른 함수에서 함수를 반환하려고 할 때 반환할 함수의 시그니처가 올바르게 지정되지 않아 컴파일 오류가 발생하고 원인을 찾는 데 오랜 시간이 걸렸습니다. 문제는 타입에 괄호가 없었기 때문입니다: fun foo(): Int -> Int 대신 올바른 fun foo(): (Int) -> Int가 필요했습니다.


이야기

개발자는 명시적으로 타입을 지정하지 않은 람다를 다른 함수의 매개변수로 사용하려고 시도했으며, 이는 "이 매개변수의 타입을 유추할 수 없습니다" 오류를 발생시켰습니다. 해결책은 람다나 함수 매개변수의 타입을 명시적으로 지정하는 것이었습니다.