코틀린 inline/reified/noinline/crossinline

Koder·2023년 1월 26일
0

inline

  • 인라인이 붙으면 코드에서는 함수라고 하지만 컴파일 시점에 호출부와 함수의 코드가 합쳐지기 때문에 콜스택 비용이 들어가지 않는다.
  • 고차함수(highOrderFunc)에서 성능 차이가 발생하며 이와 같은 함수 파라미터가 없는 경우에서는 별반 차이가 발생하지 않는다.
  • 비지역(non-local)을 반환 가능하다.
    private fun somebody(func: () -> Boolean): Boolean {
        return func()
    }

    fun test(){
		somebody {
            Random.nextBoolean()
            return
        }
    }
    // ERROR: 'return' is not allowed here
비지역 위치에서도 반환을 가능하게 하는 방법은 inline으로 선언하여 같은 scope로 인식 시키는것이다.
해결책=> fun somebody를 앞에 inline 선언
  • 인라인은 유용한점이 분명히 있지만 남발하지 않도록 정확한 의도를 확인하고 사용한다.
  • 대체적으로는 라이브러리 유틸리티 특성을 가진곳에서 성능 향상을 위해 이용하는편이다.
  • 특히 inline -> inline 콜이 되지 않도록 각별한 주의가 필요하다.

reified

  • 컴파일시 제네릭 타입속성을 리플렉션 속성으로 전환됩니다.
  • 유의할점은 인라인에서만 사용가능한것이다.
private inline fun <reified T> work() {
	println(T::class.simpleName)
}

work<Int>()

다음은 reified가 없으면 타입 추론이 불가한것을 볼수있다.

noinline

  • 함수 전체를를 inline으로 만들었으나 파라미터(고차함수)가 복수개가 존재하는 프로토타입의경우 특정한것은 제외하고 싶을때 사용할수 있다.
	inline fun somebody(
        func: () -> Boolean, 
        noinline func2: () -> Boolean,
    ): Boolean {
        return func() || func2()
    }
  • 위와 같이 func2는 inline의 영향을 받지 않게된다. (상황에 따라 조절)

crossinline

  • 인라인 고차함수 파라미터 받아서 다른 일반함수를 호출하려고 하면 일반적으로 불가능한대 이것을 가능하도록 크로스로 인라인이 처리 되도록 합니다.
    예) 인라인함수(func) -> 일반함수(func) : 이 경우 crossinline이 일반함수 처리까지 함께 해줌
	inline fun start(crossinline ff: () -> Unit){
        anybody {
            println("start")
            ff()
        }
    }

    fun anybody(f: () -> Unit){
        f()
        println("anybody")
    }


    @Test
    fun test(){
        start { println("main") }
    }
start
main
anybody

  • 만일 crossinline이 없다면 빌드시 다음과 같은 오류를 겪을수 있다.
  • 이런 경우 anybody가 inline 함수로 변하던지 그럴수 없다면 ff()를 crossinline처리 해야한다.
profile
일단 적고 보자

0개의 댓글