특정 객체에 대한 작업을 블록 안에 넣어 실행할 수 있도록 하는 여러 함수가 포함되어 있다. 제공된 람다식이 이는 개체에서 apply
, let
, run
, with
, also
총 5가지 함수를 호출하면 임시 범위가 형성된다.
수신 객체 내부 프로퍼티를 변경한 다음 수신 객체 자체를 반환하기 위해 사용되는 함수이다.
public inline fun <T> T.apply(block: T.() -> Unit): T
T
.apply 에서 T
는 apply의 수신 객체
block: T
에서 T
는 람다의 수신 객체
apply는 컨텍스트 개체 자체를 반환하므로 값을 반환하지 않고 주로 수신자 개체의 멤버에 대해 작동하는 코드 블록에 사용하는 것이 좋다.
val jw = Person("Jiwon").apply {
age = 32
city = "Seoul"
}
println(jw)
프로퍼티 설정할 때마다 person을 쓰지 않고 사용 가능하여 가독성이 좋다.
// 기존의 Person 클래스 초기화 방법
val person = Person()
person.name = "Jiwon"
person.city = "Seoul"
fun <T, R> T.let(block: (T) -> R): R
let
함수는 매개변수화된 타입 T의 확장 함수이다.
자기 자신을 받아서 R을 반환하는((T) -> R) 람다 식을 입력으로 받고, 블럭 함수의 반환값 R을 반환한다. 여기서는 Person 클래스의 확장 함수로 사용되어 person.let 의 형태가 가능해진다.
let
함수를 사용하면 객체의 상태를 변경할 수 있다.
val result = person.let {
it.name = "Jiwon"
it.age = 24
it // (T)->R 부분에서의 R에 해당하는 반환 값
}
with
는 일반 함수로, 객체를 파라미터로 직접 입력 받고, 객체를 사용하기 위한 람다 블록을 받는다.
fun <T, R> with(receiver: T, block: T.() -> R): R
receiver
로 객체를 입력받으면, it 이나 this 등 키워드 없이 객체의 속성을 참조하거나 변경할 수 있다.
val result = Person("Jiwon", 24)
with(result) {
println(name)
println(age)
}
// Jiwon
// 24
with
는 non-null
객체를 이용할 때 사용할 수 있고, 리턴을 할 수 없어 별다른 반환값이 필요하지 않을 때 사용한다.
즉, 객체의 함수나 속성을 여러번 호출할 때 코드들을 그룹핑하는 용도로 활용할 수 있다.
fun <T, R> T.run(block: T.() -> R): R
with 와 다른 점이라면,T
의 확장함수로 선언되어 있다는 점이다.
확장함수이기 때문에 with 와 다르게 Safe Call 을 붙인다면 null 객체가 들어와도 non-null 검사를 하고 실행할 수 있다.
val result = Person("Jiwon", 24)
val ageNextYear = result.run {
++age // Return
}
println("$ageNextYear")
// 25
// 마지막 실행문의 결과를 반환!!
객체의 특성
이나 메소드
등을 활용하여 어떤 값을 계산
할 필요가 있거나, 여러 개의 지역변수 범위를 제한
하고자 할 때 사용한다.
fun <R> run(block: () -> R): R
위는 확장함수가 아니고 블록에 입력값도 없다.
이는 객체 속성을 이요하려는 상황에 사용하는 것이 아닌 어떤 객체를 생성하기 위한 실행문들을 하나로 묶어 리더빌리티를 높이는 역할을 수행한다.
val person = run {
val name = "Jiwon"
val age = 24
Person(name, age) // Return
}
위와 같이 작성하면 Person에 name = Jiwon, age = 24가 저장된다.