Kotlin에는 invoke 가 존재한다. 정확히 말하자면 이는 연산자이다. 이름 없이 간단하게 호출될 수 있도록 하는 함수이다. 과연 무슨 뜻일까?
class GetPostListUseCase {
suspend operator fun invoke(page: Int): List<Post> {
...
}
}
게시물 리스트를 받아올 수 있는 UseCase가 있다. 이 경우에 위 UseCase 클래스를 아래와 같이 사용할 수 있다.
class PostViewModel(
private val postUseCase: GetPostListUseCase
) {
fun getPostList() {
viewModelScope.launch {
val postList = postUseCase(pageNum)
...
}
}
}
위 코드에서 볼 수 있듯 postUseCase의 invoke 메서드를 이름을 생략하여 호출할 수 있었다. 즉, 이름 없이 생략하여 간편하게 호출하는 함수인 것이다!
class GetPostListUseCase {
suspend operator fun invoke(page: Int): List<Post> {
...
}
}
이 코드를 다시 보면, operator 키워드가 붙어있음을 알 수 있다.
Kotlin에서는 invoke 처럼 이름을 부여한 함수임에도 불구하고, 이름을 생략하고 호출할 수 있는 것처럼 실행을 간편하게 할 수 있는 연산자를 제공한다. 아래 표와 예제 코드를 참고한다.
| Function | Code |
|---|---|
| plus | a + b |
| minus | a - b |
| div | a / b |
| rem | a % b |
| times | a * b |
| not | !a |
| unaryPlus | +a |
| unaryMinus | -a |
| inc | a++, ++a |
| dec | a--, --a |
data class Price(
val value: Int
) {
operator fun plus(price: Price): Price =
Price(value + price.value)
}
fun main() {
val a = Price(3800)
val b = Price(2500)
val result = a + b
print(result.toString()) // result = 6300
}
코틀린은 람다를 지원한다.
val convert = doSomething { action ->
action.toInt()
}
fun doSomething(action: (String) -> Unit) {
...
}
람다는 컴파일 되면서 코틀린 표준 라이브러리의 FunctionN(P1, P2 ... PN, R) 형태로 변환된다. Function 인터페이스의 구현을 살펴 보면 invoke 메서드 하나만 정의되어 있다.
따라서 위 코드가 컴파일 된다면 아래와 같다.
// compiled
val convert = object : Function1<String, Int> {
override fun invoke(p1: String): Int {
return p1.toInt()
}
}
컴파일 타임에 위처럼 변환되기 때문에, 사실상 람다를 사용하는 것은 invoke를 호출하는 것이 된다.
따라서, convert.invoke("3")를 호출하는 것이 아니라 convert("3") 처럼 호출할 수 있게 되는 것이다.
좋은 글 감사합니다