언어/코틀린

코틀린 범위 지정 함수(apply, run, with, let, also)

ballde 2022. 7. 18. 11:01

정의

  • 수신 객체 지정 람다함수
  • 특정 객체에 대한 작업을 블록 안에 넣어 실행할 수 있도록 하는 함수
  • 이름에 따라서 범위 지정이 달라진다.
  • apply, run, with, let, also

this: 수신 객체를 람다의 수신 객체로 전달하기 때문에

lt: 수신객체를 람다의 파라미터로 접근하기 때문에

명시하지 않거나 this로 접근 lt 로 접근

수신 객체 자체 apply also
Block의 마지막 줄 run, with let

apply

  • apply는 수신 객체 내부 프로퍼티를 변경한 다음 수신 객체 자체를 반환
  • apply 블록 안에서는 오직 프로퍼티만 사용
public inline fun <T> T.apply(block: T.() -> Unit): T
class Customer(val name: String) {

    private var _message: List<String>? = null

    val messages: List<String>
        get() {
            if (_message == null) {
                _message = loadMessages()
            }
            return _message!!
        }

    private fun loadMessages(): List<String> =
        mutableListOf(
            "hello",
            "sldkf",
            "slkdf"
        ).also { println("1 loaded messages") }

}

val customer = Customer("name").apply { this.messages }
  • 람다식의 수신 객체가 apply의 수신 객체이므로 this 생략이 가능하다.
  • 프로퍼티 설정때마다 person을 사용하지 않아서 가독성이 좋다.

run

  • 수신 객체 내부 프로퍼티를 변경한 후 수신 객체를 return 하지 않고 run의 마지막 줄을 return
  • 결과 값을 return 받아야 하는 경우 사용
public inline fun <T, R> T.run(block: T.() -> R): R
class Customer(val name: String) {
		...

    fun isCustomer(): Boolean {
        return false
    }

}
// 사용법 1
val customer2 = Customer("name").run { isCustomer() }
println(customer2).  // false

// 사용법 2
val customer3 = Customer("name")
val name = run {
    customer3.name
}
println(name)

with

  • 수신 객체에 대한 작업 후 마지막 라인을 return 한다.
  • run 과 똑같이 작동
  • run은 확장함수로 사용, with는 수신 객체를 파라미터로 받아서 사용
public inline fun<T, R> with(receiver: T, block: (T) -> R): R
class Customer(val name: String) {
		...

    fun isCustomer(): Boolean {
        return false
    }

}
val name = with(customer3) {
    customer3.name
}

let

  • 수신 객체를 이용해 작업 후 마지막 줄을 return
  • 수신객체를 접근 할 때 it 를 사용
  • with, run과 똑같이 작동
public inline fun <T, R> T.let(block: (T) -> R): R
class Customer(val name: String) {
		...

    fun isCustomer(): Boolean {
        return false
    }

}
val customer3 = Customer("sdf").let { 
    println("다른 작업 하고")
    it.isCustomer()
}

let의 사용

  • null check 후 코드를 실행해야 하는 경우
  • nullable한 수신 객체를 다른 타입의 변수로 변환해야하는 경우
val customer: Customer? = null
customer?.let {
    it: Customer -> it.name
}
  • let은 null이 아닐때만 사용된다.
  • ?.let을 사용하면 let 블락 안에서는 Customer 이된다.

also

  • apply와 같이 수신객체 자신을 반환
  • apply는 프로퍼티 세팅 후 반환
  • also는 프로퍼티 세팅뿐만 아니라 객체에 대한 추가적인 작업
public inline fun <T> T.also(block: (T) -> Unit): T

'언어 > 코틀린' 카테고리의 다른 글

동등성, 동일성 연산(==, ===)  (0) 2022.07.18