Scope 함수
Scope 함수란 객체를 할당하고 배정할 수 있는 공간인 Object context 내에서 코드 블록을 실행하기 위한 목적만을 가진 함수입니다.
Scope 함수들을 람다식으로 호출할 때, 이는 임시로 범위(scope)를 형성합니다. 이 범위 내에서는 객체의 이름이 없어도 객체에 접근할 수 있습니다.
이러한 용도로 코드들을 더욱 간결하고 가독성을 좋게 합니다.
let
inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)
}
// <T, R> -> 타입 파라미터
// (T) -> 리시버 -> it
// : R -> 리턴 타입 - 블럭에 마지막 코드
val length = str?.let {
it.length
} ?: 0
타입 파라미터 <T, R>이란 Scope함수를 사용할 타입인 T와 리턴값인 R을 의미합니다.
T.let에서 알 수 있다 시피 let 함수는 str?. let처럼 사용할 변수 뒤에 붙습니다.
또한 block: (T)에서 T를 인자로 받고 있기 때문에 코드 블록 내에서 it을 사용합니다.
마지막으로 코드블록 내의 결괏값, 즉 코드블록의 마지막 코드를 반환합니다.
위의 예제와 같이 객체의 값이 null이 아닐 때 let을 실행시키고 null일 때에 엘비스 연산자인?:을 통해 null 값을 처리하는 용도로 사용됩니다.
run
inline fun <T, R> T.run(block: T.() -> R): R {
return block()
}
val service = MultiportService("<https://example.kotlinlang.org>", 80)
val result = service.run {
port = 8080
query(prepareRequest() + " to port $port")
}
let과 마찬가지로 사용할 변수 뒤에 붙습니다.
하지만 block: T.()이기 때문에 this를 사용하고 생략이 가능합니다.
결괏값은 let과 같이 코드블록 내의 결괏값을 반환합니다.
run은 객체의 초기화, 객체 내의 어떤 값이나 특정한 값이 필요할 때 사용됩니다.
with
inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
val numbers = mutableListOf("one", "two", "three")
with(numbers) {
println("'with' is called with argument $this")
println("It contains $size elements")
}
다른 scope 함수와 달리 T.with이 아닌 with이고 receiver: T가 있기 때문에 with(T)으로 사용합니다.
T.()과 R이기 때문에 run처럼 this를 사용하고 run과 let처럼 코드블럭내의 결과값을 반환합니다.
객체의 함수를 여러 개 호출할 때 그룹화하는 용도로 사용합니다.
apply
inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
val adam = Person("Adam").apply {
age = 32
city = "London"
}
앞의 예제들과 달리 R이 Unit으로 바뀌었습니다. 이는 결괏값으로 해당 객체를 반환한다는 뜻입니다. return this 보이시죠?
또한 T.()이기 때문에 this를 사용합니다.
객체의 생성과 초기화에 주로 사용됩니다.
also
inline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
val numbers = mutableListOf("one", "two", "three")
numbers
.also { println("The list elements before adding new one: $it") }
.add("four")
apply와 마찬가지로 객체를 반환합니다. 또한 (T)이기 때문에 it을 사용합니다.
로깅이나 디버그 정보를 출력하는 것과 같이 객체를 변화시키지 않는 부가적인 작업을 하는 용도로 사용합니다.
마무리
총정리를 해보자면
it | this | |
객체 | also | apply |
코드블럭 | let | run, with |
사용하는 용도가 명확히 정해져 있는 건 아니니 편한 대로 사용하면 됩니다.
this는 생략할 수 있어 깔끔한 코드를 만들 수 있고 it은 원하는 대로 명칭을 바꿀 수 있어 가독성을 좋게 할 수 있습니다.
또한 객체를 반환하는 것은 객체의 초기화와 인스턴스 생성을 동시에 할 때 좋고 코드블럭은 특정 값이 필요할 때 좋습니다.
※ 잘못된 정보, 혹은 다른 의견이 있다면 댓글로 말해주세요. 감사합니다.
'Android > Kotlin' 카테고리의 다른 글
백킹프로퍼티(Backing Properties)란? (0) | 2023.04.06 |
---|---|
Kotlin 연산자 - ? / !! / ?: / is / as (0) | 2023.02.22 |
List, Set, Map (0) | 2023.02.20 |