Kotlin

[Kotlin] invoke 함수

Zibro 2025. 1. 15. 22:15
728x90
반응형

Kotlin의 invoke()는 무엇인가?

코틀린(Kotlin)에는 이름 없이 호출할 수 있는 특별한 함수, 정확히는 연산자인 invoke()가 존재합니다. 이 함수는 객체를 마치 함수처럼 사용할 수 있도록 만들어 주는 강력한 기능을 제공합니다. 아래의 예제를 통해 invoke()의 동작을 살펴보겠습니다.

class Example {
    operator fun invoke(str: String): String {
        return str.toUpperCase()
    }
}

위 코드는 Example 클래스에 invoke() 연산자를 정의한 예제입니다. 이 invoke()는 일반 메서드처럼 호출할 수 있습니다:

val example = Example()
println(example.invoke("hello")) // HELLO

그러나 코틀린에서는 invoke라는 이름의 함수는 이름 없이 호출될 수 있습니다. 즉, 아래와 같이도 동일한 결과를 얻을 수 있습니다:

println(example("hello")) // HELLO

invoke() 연산자는 객체를 함수처럼 사용할 수 있는 특별한 역할을 수행합니다.


연산자(operator) 키워드

invoke()와 같이 특정 함수에 operator 키워드를 붙이면, 해당 함수는 코틀린에서 제공하는 연산자로 동작할 수 있습니다. 예를 들어, plus 함수는 + 연산자로 사용할 수 있습니다:

object Sample {
    operator fun plus(str: String): String {
        return this.toString() + str
    }
}

fun main() {
    println(Sample + " Hello~!") // [Sample의 주소값] Hello~!
}

위 코드는 Sample 객체와 문자열을 더하는 동작을 보여줍니다. plus 함수는 + 연산자를 통해 호출되며, 이를 통해 더 간결하고 직관적인 코드 작성을 가능하게 합니다.


람다와 invoke

코틀린은 람다를 지원하며, 람다는 함수처럼 동작하는 객체입니다. 다음은 람다의 간단한 예제입니다:

val toUpperCase = { str: String -> str.toUpperCase() }

람다에도 타입이 존재하며, 위의 람다는 (String) -> String 타입입니다. 더 정확히는, 코틀린 표준 라이브러리에 정의된 Function<P1, R> 인터페이스 타입입니다. 이 인터페이스는 invoke() 연산자 하나만 포함하고 있습니다.

Function<P1, R>의 동작을 살펴보면 다음과 같습니다.

val toUpperCase = object : Function1<String, String> {
    override fun invoke(p1: String): String {
        return p1.toUpperCase()
    }
}

람다는 결국 컴파일 시점에 invoke() 연산자를 가진 객체로 변환됩니다. 따라서 다음 두 코드는 동일하게 동작합니다:

println(toUpperCase.invoke("hello")) // HELLO
println(toUpperCase("hello")) // HELLO

invoke와 컬렉션 함수

람다를 활용하면 컬렉션 함수에서도 invoke를 간편하게 사용할 수 있습니다. 예를 들어, 다음 코드는 리스트의 모든 문자열을 대문자로 변환합니다:

fun main() {
    val strList = listOf("a", "b", "c")
    println(strList.map(toUpperCase)) // [A, B, C]
}

map 함수는 리스트의 요소를 순회하며 각 요소에 대해 toUpperCase를 호출합니다. toUpperCaseinvoke 연산자를 가지고 있기 때문에 별도의 메서드 호출 없이 간단히 사용할 수 있습니다.

또한, 위 코드는 람다를 직접 사용하는 방식으로도 작성할 수 있습니다:

fun main() {
    val strList = listOf("a", "b", "c")
    println(strList.map { str: String -> str.toUpperCase() }) // [A, B, C]
}

람다는 컴파일러에 의해 invoke 연산자를 가진 객체로 변환되므로, 두 방식 모두 동일한 결과를 제공합니다.


invoke() 함수는 코틀린의 강력한 특징 중 하나로, 객체를 함수처럼 호출할 수 있게 만들어줍니다. 이를 통해 코드는 더욱 간결하고 직관적으로 변합니다. 특히 람다와 컬렉션 함수와 함께 사용하면 코드의 가독성과 표현력을 크게 향상시킬 수 있습니다.

728x90
반응형