Scope 함수들은 어떤 객체의 context에서 코드를 실행할 수 있도록 해주는 함수들입니다. 이 함수들은 lambda를 이용해 임시 scope를 만들고, 그 scope 안에서는 해당 객체의 이름을 사용하지 않고 접근할 수 있도록 해줍니다.

Scope 함수에 해당하는 let, with, run, apply, also 5개의 함수들은 비슷한 기능을 갖고 있습니다.

이 함수들 간의 차이점은 context 객체에 접근하는 방법과 return 값 입니다.

run, with, applythis로 객체에 접근하고, let, alsoit으로 객체에 접근합니다.

apply, also는 객체를 return하고, let, run, with는 lambda 결과를 return합니다.

let

letit을 통해 객체에 접근할 수 있고, return값은 lambda 결과입니다.

data class Person(val name: String, val age: Int)

fun main() {

    val person = Person("John", 25)

    val result = person.let {

        println(it.name)
        println(it.age)
        
        "${it.name} is ${it.age} year old"
        
    }

    println(result)

}

또한, 아래와 같이 safe call 연산자 ?.를 이용하면 null이 아닌 경우에만 lambda 코드를 실행할 수 있도록 할 수 있습니다.

이 방법을 이용하면 if(person != null) {} 같은 코드를 대신할 수 있습니다.

val person: Person? = null

person?.let {
    println(it.name)
}

with

with는 객체를 파라미터로 받고 this를 통해 접근할 수 있습니다. return값은 let과 동일하게 lambda 결과입니다.

with는 객체를 이용한 함수들을 호출 할 때 유용합니다.

data class Person(val name: String, val age: Int)

fun main() {

    val person = Person("John", 25)

    with(person) {
        println(this.name)
        println(this.age)
    }

}

run

runwith와 거의 비슷하지만 확장 함수입니다.

run은 lambda 안 에서 객체의 정의와 객체를 사용한 연산을 모두할 때 유용합니다.

data class Person(var name: String?)

fun main() {

    val person = Person(null)

    person.run {
        name = "John"
        println(this.name)
    }

}

apply

applythis로 객체에 접근하고, return 값은 객체 자신입니다. (this는 생략해도 됩니다.)

apply는 객체의 값들을 설정하는데에 주로 쓰입니다.

class Person {
    var name: String? = null
    var age: Int? = null
}

fun main() {

    val person = Person().apply {
        name = "John"
        age = 25
    }

    println(person.name)
    println(person.age)

}

also

alsoit으로 객체에 접근하고, return 값은 객체 자신입니다.

also는 객체를 이용한 함수들을 호출할 때, 외부 scope의 this를 가리지 않고 싶을 때 유용합니다.

data class Person(val name: String, val age: Int)

fun main() {

    val person = Person("John", 25)

    person.also {
        println(it.name)
        println(it.age)
    }

}

위 함수들은 비슷한 역할들을 하지만 조금씩 다른 특징이 있기 때문에, 상황에 적합한 함수를 선택해 사용하는 것이 좋습니다.