Programming Language/Kotlin
[Kotlin] Scope Function 정리 (let, run, with, apply, also)
Tenacity_Dev
2023. 1. 1. 16:26
728x90
스코프 함수란?
코틀린에서는 Object Context 내에서 코트 블록을 실행하는 것이 목적인 여러 함수가 존재한다.
제공된 람다식을 사용하여 객체에 이러한 함수들을 호출하면 임시적으로 스코프(범위)가 설정된다. 이 범위에서는 해당 객체의 이름없이 접근할 수있다.
스코프 함수에는 5가지의 함수가 존재하는데,
let, run, with, apply, also
공통점으로는 객체에 붙어있는 코드 블록을 실행시킨다는 것이다.
이에 차이점과 각 함수의 특징들에 대해서 정리해보자.
5가지의 함수의 정의이다.
inline fun <T, R> T.run(block: T.() -> R): R {
return block()
}
inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
inline fun <T> T.apply(block: T.() -> Unit): T {
block()
return this
}
inline fun <T> T.also(block: (T) -> Unit): T {
block(this)
return this
}
inline fun <T, R> T.let(block: (T) -> R): R {
return block(this)
}
1. let
- let 함수는 확장 함수이기 때문에 context object를 receiver(this)로 전달한다. 그러나, 코드 블럭내에서 this를 파라미터로 입력하기 때문에 it을 사용해 프로퍼티에 접근할 수 있다.
- let 함수는 반환 결과가 람다의 결과이다.
- let함수는 지정된 값이 null이 아닌 경우에 코드를 실행해야 하는 경우, Nullable 객체를 다른 Nullable 객체로 변환하는 경우, 단일 지역 변수의 범위를 제한하는 경우에 유용하다.
getMember()?.let {
// null이 아닐때만 실행
println(it) // it: member
}
2. run
- run 함수는 확장함수이기 때문에 context object를 receiver(this)로 이용할 수 있다.
- run 함수는 반환결과가 람다의 결과이다.
- run 함수는 객체의 초기화와 리턴 값의 계산을 람다가 포함할 때 유용하다.
- 확장함수이기 때문에 safe call(.?)을 붙여 non-null일 때에만 실행할 수 있다.
- 주로 어떤 값을 계산할 필요가 있거나 여러개의 지역변수 범위를 제한할 때 사용한다.
data class Member(val name: String, var age: Int)
val member = Member("Wangi", 26)
val nextYearHisAge = member.run {
++age // this.age
}
println(nextYearHisAge) // 27
val member = run {
val name = "Wangi"
val age = 26
Member(name, age)
}
rum은 단지 어떤 객체를 생성하여 명령문을 블록 안에 적음으로써 가독성을 높이는 역할을 한다.
3. with
- with 함수는 확장 함수가 아니기 때문에 context object를 argument로 전달한다. 그러나, 람다의 내부에는 확장 함수로 적용되어서 this가 사용 가능하다.
- with함수는 반환결과가 람다의 결과이다.
- with 함수는 수신객체가 non-nullable이고, 결과가 필요하지 않은 경우에 유용하다.
val member = Member("Wangi", 26)
with(member) {
println("This member name is $name") // this.name
println("This member age is $age") // this.age
}
4. apply
- apply 함수는 확장 함수이기 때문에 context object를 receiver(this)로 이용할 수 있다.
- apply 함수는 반환 결과가 객체 자신이다. Builder 패턴과 동일한 용도로 사용된다.
- apply 함수는 객체의 프로퍼티 만을 사용하는 경우가 많으며, 대표적인 사례는 객체의 초기화이다.
val member = Member("Wangi").apply{
age = 26 // this.age
}
println(member) // Member(name=Wangi, age=26)
5. also
- also 함수는 확장 함수이기 때문에 context object를 receiver(this)로 전달한다. 그러나, 코드 블럭 내에서 this를 파라미터로 입력하기 때문에 it을 사용해 프로퍼티에 접근할 수 있다.
- also 함수는 반환 결과가 객체 자신이다. Builder 패턴과 동일한 용도로 사용된다. (Bulider 패턴은 나중에 디자인패턴을 정리할때 설명하겠다.)
- also 함수는 객체의 속성을 전혀 사용하지 않거나 변경하지 않고 사용하는 경우에 유용하다. 예를 들면, 객체의 데이터 유효성을 확인하거나, 디버그, 로깅 등의 부가적인 목적으로 사용할 때에 적합하다.
class Membership(member: Member) {
val member = member.also {
requireNotNull(it.age)
println(it.name)
}
}
참고 :
https://kotlinlang.org/docs/scope-functions.html
코틀린 공식문서를 보고 정리하였습니다.
728x90