코틀린 표준 라이브러리에는 어떤 식을 계산한 값을 문맥 내부에서 임시로 사용할 수 있도록 해주는 영역 함수가 있는데 지역 변수를 명시적으로 선언하지 않고, 식의 값이 들어있는 암시적인 영역을 정의해서 코드를 단순화할 수 있는데 이 함수를 영역 함수
라고 하며 영역 함수의 종류에는 run, let,with, apply, also
있다.
run()
함수는 확장 람다를 받는 확장 함수이며 람다의 결과를 돌려준다.
inline fun <R> run(block: () -> R): R
즉, 수신 객체에 대해 특정한 동작을 수행한 후 결과값을 리턴 받을 때 사용한다.
fun main() {
val isReceived = Address().run {
//Address 인스턴스를 this로 사용할 수 있다.
zipCode = 123456
city = "London"
street = "Baker Street"
house = "221b"
post("안녕하세요!")
}
if (!isReceived) {
println("메시지가 전달되지 않음")
}
}
class Address {
var zipCode: Int = 0
var city: String = ""
var street: String = ""
var house: String = ""
fun post(message: String): Boolean {
println("Message for{$zipCode,$city, $street,$house} : $message")
return readlnOrNull() == "OK"
}
}
with()
함수는 run()
과 비슷하며 차이점은 with( )가 확장 타입이 아니므로 문맥 식을 with의 첫 번째 인자로 전달해야 한다. 이 함수는 문맥 식의 멤버 함수와 프로퍼티에 대한 호출을묶어 동일한 영역 내에서 실행하는 경우이다.
inline fun <T, R> with(receiver: T, block: T.() -> R): R
fun main() {
val message = with(Address("한국","충청남도","111")){
"Address: $city, $street, $house"
}
println(message)
}
class Address(val city: String, val street: String, val house: String)
run()과 비슷하지만 확장 함수 타입의 람다를 받기 않고 인자가 하나뿐인 함수 타입의 람다를 받는 점이 다르다.
let
은 다음과 같은 경우 사용된다.
inline fun <T, R> T.let(block: (T) -> R): R
fun main() {
Address("부산","Baker Street","221b").let{
println("To city: ${it.city}")
it.post("안녕하세요.")
}
}
class Address(val city:String, val street:String,val house:String){
fun post(message:String){}
}
확장 람다를 받는 확장 함수이며 자신의 수신 객체를 반환한다. 이 함수는 일반적으로 run()과 달리 반환값을 만들어내지 않고 객체의 상태를 설정하는 경우에 사용한다.
inline fun <T> T.apply(block: T.() -> Unit): T
fun main() {
val message= readln()?:return
Address().apply {
city="속초"
street="카페거리"
house="222"
}.post(message)
}
class Address {
var city:String=""
var street:String=""
var house:String=""
fun post(message:String){}
}
apply와 비슷한 함수이며 다른점은 인자가 하나 있는 람다를 파라미터로 받는다.
inline fun <T> T.also(block: (T) -> Unit): T
fun main() {
val message= readln()?:return
Address().also {
it.city="속초"
it.street="카페거리"
it.house="222"
}.post(message)
}
class Address {
var city:String=""
var street:String=""
var house:String=""
fun post(message:String){}
}
참고
https://kotlinlang.org/docs/scope-functions.html#run
https://kotlinworld.com/255#run
코틀린 완벽가이드 책