Scope Function
- Kotlin 표준 라이브러리에는 객체 내에서 코드 블록을 실행하는 것이 유일한 목적인 여러 함수가 포함되어 있다.
- 제공 되는
람다식이 있는 개체에서 이러한 함수를 호출하면 임시 범위(Scope)가 형성 된다.
- 이 범위에서는 이름 없이 개체에 접근할 수 있으며 이러한 함수를
Scope Function 이라고 한다.
Scope Function 종류
- Scope Function에는
let, run, with, apply, also가 있다.
| Function | Object reference | Return value | Is extension function |
|---|
| let | it | Lambda result | Yes |
| run | this | Lambda result | Yes |
| run | - | Lambda result | No: context 개체 없이 호출됨 |
| with | this | Lambda result | No: Context 개체를 인수로 사용함 |
| apply | this | Context object | Yes |
| also | it | Context object | Yes |

어떤 상황에 어떤 함수를 써야하는지 정확히 이해하지 못하고 매번 헷갈렸는데 이 그림을 외워야할 것 같다..😅
let
| 함수 | 객체 참조 | 반환 값 | 확장 함수 |
|---|
| let | it | Lambda result | Yes |
- let은 extension function이며 반환 값이 Lamda result이다.
- 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있다.
객체를 생성하거나 사용하는 시점에서 이름을 부여하여 다양한 작업을 수행시키고 결과를 돌려받고 싶을 때 유용하다.
val numbers = mutableListOf("one", "two", "three", "four", "five")
val resultList = numbers.map { it.length }.filter { it > 3 }
println(resultList)
val letNumbers = mutableListOf("one", "two", "three", "four", "five")
letNumbers.map { it.length }.filter { it > 3 }.let {
println(it)
}
val str: String? = "Hello"
val length = str?.let {
println("let() called on $it")
it.length
}
val numbers = listOf("one", "two", "three", "four")
val modifiedFirstItem = numbers.first().let { firstItem ->
println("첫번째 요소 '$firstItem'")
if (firstItem.length >= 5) firstItem else "!$firstItem!"
}.uppercase()
println("수정 후 첫 번째 요소: '$modifiedFirstItem'")
run
| 함수 | 객체 참조 | 반환 값 | 확장 함수 |
|---|
| run | this | Lambda result | Yes |
| run | - | Lambda result | No: context 개체 없이 호출됨 |
- run은 단일 Lamda function을 인자로 받는 버전과 extension function으로 이루어진 버전이 있다.
- 두 개 모두 반환 값은 Lamda result이며 임의로 생성한 값이나 객체를 반환할 수 있다.
- 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있다.
객체를 생성하거나 사용하는 시점에서 다양한 작업을 수행시킨 후 결과를 반환 받고 싶을 때 유용하다.
class MultiportService(var url: String, var port: Int) {
fun prepareRequest(): String = "Default request"
fun query(request: String): String = "Result for query '$request'"
}
fun main() {
val service = MultiportService("https://example.kotlinlang.org", 80)
val result = service.run {
port = 8080
query(prepareRequest() + " to port $port")
}
println(result)
}
val adam = Person("Adam", 32, "London")
val nextAge = adam.run {
++age
}
println(nextAge)
with
| 함수 | 객체 참조 | 반환 값 | 확장 함수 |
|---|
| with | this | Lambda result | No: Context 개체를 인수로 사용함 |
- with는 extenstion function이 아니며 객체를 argument로 받아 사용한다.
- 두 번째 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있으며 반환 값은 Lamda result이다.
- with는
이미 생성된 객체에 일괄적인 작업을 처리할 때 유용하다.
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
val firstItem = first()
val lastItem = last()
println("First item: $firstItem, last item: $lastItem")
}
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
println("'with' 는 ${this} 로 참조합니다.")
println("${size}개의 요소를 포함합니다.")
}
run과 with의 차이점
run과 with는 유사하지만 run은 extension function 버전으로 인해 객체를 생성해서 할당하기 전에 사용이 가능하다는 차이가 있다.
apply
| 함수 | 객체 참조 | 반환 값 | 확장 함수 |
|---|
| apply | this | Context object | Yes |
- apply extension function이며 반환 값이 Context object이다.
- 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있다.
- 객체에
무언가를 적용(apply)할 때나 객체 생성시점에 초기화를 할 때 유용하다.
data class Person(var name: String, var age: Int = 0, var city: String = "")
fun main() {
val adam = Person("Adam").apply {
age = 32
city = "London"
}
println(adam)
}
val adam = Person("Adam")
adam.age = 32
adam.city = "London"
also
| 함수 | 객체 참조 | 반환 값 | 확장 함수 |
|---|
| also | it | Context object | Yes |
- also는 extension function이며 반환 값이 Context object이다.
- 인자로 Lamda funtion을 받기 때문에 곧바로 Lamda funtion에 해당하는 코드 블록을 작성할 수 있다.
- 객체에게
명령을 내리기 직전에 추가적인(also) 작업을 함께 수행시키고 싶을 때 유용하다.
val numbers = mutableListOf("one", "two", "three")
numbers
.also { println("$it") }
.add("four")
apply와 also의 차이점
apply와 also는 유사하지만 apply는 Lamda funtion에 인자를 넘겨주지 않기 때문에 this를 이용해 참조한다.
그에 반해 also는 Lamda function에 인자를 넘겨주기 때문에 인자를 it이나 다른 이름을 부여해 참조가 가능하다.
참조
코틀린(Kotlin)의 Scope Function(let, with, run, apply, also) 정리
Kotlin Scope function 올바르게 사용하기
Scope Function