ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 17강. 코틀린에서 람다를 다루는 방법
    BackEnd/Kotlin 2024. 4. 7. 07:00
    반응형
    1. Kotlin 람다
    2. Closure

     

    Kotlin 람다

      Kotlin의 람다는 Java와 근본적으로 다른 한 가지가 있습니다.

    • Java: 함수는 변수에 할당되거나 파라미터로 전달할 수 없습니다. (2급 시민)
    • Kotlin: 함수가 그 자체로 값이 될 수 있습니다. 변수에 할당할 수도, 파라미터로 넘길 수도 있습니다. (1급 시민)

     

      다음은 Kotlin에서 람다를 만드는 방법과 호출하는 방법입니다.

    fun main() {
        val fruits = listOf(
            Fruit("사과", 1_000),
            Fruit("사과", 1_200),
            Fruit("사과", 1_200),
            Fruit("사과", 1_500),
            Fruit("바나나", 3_000),
            Fruit("바나나", 3_200),
            Fruit("바나나", 2_500),
            Fruit("수박", 10_000),
        )
    
        // 람다를 만드는 방법 1
        val isApple: (Fruit) -> Boolean = fun(fruit: Fruit): Boolean {
            return fruit.name == "사과"
        }
    
        // 람다를 만드는 방법 2
        val isApple2: (Fruit) -> Boolean = { fruit: Fruit -> fruit.name == "사과" }
    
    
        // 람다를 호출하는 방법 1
        isApple(Fruit("사과", 1000))
    
        // 람다를 호출하는 방법 2
        isApple.invoke(Fruit("사과", 1000))
    }
    • 함수의 타입: (파라미터 타입...) -> 반환 타입 입니다. 람다를 만들 때 생략 가능합니다.

     

      다음은 람다(익명함수)를 파라미터로 받는 함수입니다.

    private fun filterFruits(fruits: List<Fruit>, filter: (Fruit) -> Boolean): List<Fruit> {
        val results = mutableListOf<Fruit>()
        for (fruit in fruits) {
            if (filter.invoke(fruit)) {
                results.add(fruit)
            }
        }
        return results
    }

     

      (Fruit) -> Boolean 함수 타입이 동일하기 때문에 다음과 같이 호출하여 사용할 수 있습니다.

        filterFruits(fruits, isApple)
        filterFruits(fruits, isApple2)

     

      람다는 익명함수이기 때문에 변수에 할당하지 않고, 다음과 같이 직접 넣어줘도 됩니다.

         filterFruits(fruits, { fruit: Fruit -> fruit.name == "사과" })

     

      함수(filterFruits)에서 받는 함수 파라미터(filter)가 마지막에 위치한다면, 다음과 같이 소괄호 밖에서 람다를 사용할 수 있습니다.

        filterFruits(fruits) { fruit: Fruit -> fruit.name == "사과" }

     

      Kotlin에서 파라미터가 한 개인 경우, 다음과 같이 it을 사용할 수도 있습니다.

        filterFruits(fruits) { it.name == "사과" }

     

    Closure

      Java에서 람다를 쓸 때 사용할 수 있는 변수에 제약이 존재합니다. 다음 코드는 Variable used in lambda expression should be final or effectively final 이 발생합니다. 즉, Java에서 람다는 final인 변수 혹은 실질적으로 final인 변수만 사용이 가능합니다.

     

      Kotlin에서는 다음과 같이 아무런 문제 없이 동작합니다. Kotlin에서는 람다가 시작하는 지점에 참조하고 있는 변수들을 모두 포획하여 그 정보를 가지고 있기 때문입니다. 이러한 데이터 구조를 Closure라고 부릅니다.

        var targetFruitName = "바나나"
        targetFruitName = "수박"
        filterFruits(fruits) { it.name == targetFruitName }

     

     

     

    감사합니다.

    반응형

    댓글

Designed by Tistory.