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