스코프 함수

객체의 컨텍스트 내에서 특정 동작을 실행하기 위한 목적만을 가진 함수

스코프 함수를 람다 함수로 사용하게 되면 임시로 스코프를 형성하는데 이 스코프 내에서는

객체의 이름을 통해 **일일히 참조할 필요 없이 객체를 접근하고 핸들링할 수 있다는 장점**이 있다

종류는 총 apply, run, with, also, let


apply

public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}

객체를 새로 생성하고 특정 변수에 할당 전에 초기화 작업을 하는 스코프 생성

apply 함수 내에 모든 명령들이 수행되고 나면 명령들이 적용된 새로운 객체를 반환

fun main() {
		var coffee = Coffee("아메리카노", 1500).apply {
				this.name = "이벤트 $name"
				event()
}

		println("${coffee.name}의 ${coffee.price}원)
}

class Coffee(var name: String, var price: Int) {
		fun event() {
				price -= 1000
	}
}

// 결과 : 이벤트 아메리카노의 500원

// apply로 인해서 Coffee 객체가 이름은 아메리카노 가격은 1500으로 생성됐다

run

public inline fun <T, R> T.run(block: T.() -> R): R {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    return block()
}