[Kotlin] invoke 함수
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
를 호출합니다. toUpperCase
는 invoke
연산자를 가지고 있기 때문에 별도의 메서드 호출 없이 간단히 사용할 수 있습니다.
또한, 위 코드는 람다를 직접 사용하는 방식으로도 작성할 수 있습니다:
fun main() {
val strList = listOf("a", "b", "c")
println(strList.map { str: String -> str.toUpperCase() }) // [A, B, C]
}
람다는 컴파일러에 의해 invoke
연산자를 가진 객체로 변환되므로, 두 방식 모두 동일한 결과를 제공합니다.
invoke()
함수는 코틀린의 강력한 특징 중 하나로, 객체를 함수처럼 호출할 수 있게 만들어줍니다. 이를 통해 코드는 더욱 간결하고 직관적으로 변합니다. 특히 람다와 컬렉션 함수와 함께 사용하면 코드의 가독성과 표현력을 크게 향상시킬 수 있습니다.