Kotlin/note

[Kotlin] Scope Functions (let/run/with/apply/also)

김 안개 2023. 8. 16. 22:39

헷갈리기만 했던 scope 함수들 정리해보자 -!

 

 


apply

public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

 

  • Object 를 수신자(Receiver)로 사용가능하며, this 로 접근 가능
  • Object 반환
  • 사용하는 경우
    • 주로 객체 초기화 및 속성 설정을 한 번에 수행할 때 사용

also

public inline fun <T> T.also(block: (T) -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block(this)
    return this
}

 

  • Object 를 argument 로 받아들여 사용가능하며, it 으로 접근 가능
  • Object 반환
  • 사용하는 경우
    • 주로 중간 단계의 계산 혹은 작업의 부작용을 로깅할 때 사용

let

public inline fun <T, R> T.let(block: (T) -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block(this)
}

 

  • Object 를 argument 로 받아들여 사용가능하며, it 으로 접근 가능
  • Lambda 식의 결과를 반환
  • 사용하는 경우
    • Nullable 객체에 대해 안전하게 함수를 호출할 때 사용
    • 1개 이상의 함수를 호출할 때에도 사용
    • 코드의 가독성과 안전성을 향상시키는데 도움

run

public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}

 

  • Object 를 수신자(Receiver)로 사용가능하며, this 로 접근 가능
  • Lambda 식의 결과를 반환
  • 사용하는 경우
    • 객체의 초기화를 진행하면서 중간 단계의 결과를 출력할 때 사용
    • 객체의 메서드/속성을 활용하여 계산을 진행할 때 사용

with

public inline fun <T, R> with(receiver: T, block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return receiver.block()
}

 

  • Object 를 수신자(Receiver)로 사용가능하며, this 로 접근 가능
  • Lambda 식의 결과를 반환
  • 확장 함수가 아님 -> 다른 스코프 함수처럼 .을 통해 사용 불가능
  • 사용하는 경우
    • 반환값이 필요하지 않는 경우
    • 객체의 특정 멤버에 접근할 때 사용

 

출처