Kotlin - invoke

Park Suyong·2022년 6월 14일
1

Kotlin

목록 보기
5/7

Kotlin에는 invoke 가 존재한다. 정확히 말하자면 이는 연산자이다. 이름 없이 간단하게 호출될 수 있도록 하는 함수이다. 과연 무슨 뜻일까?

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)
            ...
        }
    }
}

위 코드에서 볼 수 있듯 postUseCaseinvoke 메서드를 이름을 생략하여 호출할 수 있었다. 즉, 이름 없이 생략하여 간편하게 호출하는 함수인 것이다!

operator

class GetPostListUseCase {
	suspend operator fun invoke(page: Int): List<Post> {
    	...
    }
}

이 코드를 다시 보면, operator 키워드가 붙어있음을 알 수 있다.

Kotlin에서는 invoke 처럼 이름을 부여한 함수임에도 불구하고, 이름을 생략하고 호출할 수 있는 것처럼 실행을 간편하게 할 수 있는 연산자를 제공한다. 아래 표와 예제 코드를 참고한다.

FunctionCode
plusa + b
minusa - b
diva / b
rema % b
timesa * b
not!a
unaryPlus+a
unaryMinus-a
inca++, ++a
deca--, --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") 처럼 호출할 수 있게 되는 것이다.

profile
Android Developer

1개의 댓글

comment-user-thumbnail
2022년 12월 13일

좋은 글 감사합니다

답글 달기