TIL

Delegated properties

코틀린의 Delegated Properties

// val/var <프로퍼티명>: <타입> by <표현식>

표준 위임 객체

지연 초기화 프로퍼티 (Lazy)

val lazyValue: String by lazy {
    println("계산 중...")
    "Hello"
}

Observable Properties

var name: String by Delegates.observable("초기값") { 
    prop, old, new -> println("$old -> $new") 
}

다른 프로퍼티에 위임

class Example {
    var newName: String = "Kotlin"
    
    @Deprecated("이 프로퍼티는 곧 삭제될 예정입니다")
    var oldName: String by ::newName
}

맵에 프로퍼티 저장

class User(val map: Map<String, Any?>) {
    val name: String by map
    val age: Int by map
}

val user = User(mapOf(
    "name" to "John Doe",
    "age" to 25
))

println(user.name) // Prints "John Doe"
println(user.age)  // Prints 25

로컬 위임 프로퍼티

fun example(computeFoo: () -> Foo) {
    val memoizedFoo by lazy(computeFoo)

    if (someCondition && memoizedFoo.isValid()) { // 여기서 접근할 때 할당
        memoizedFoo.doSomething() 
    }
}

위임 객체 요구사항

class Resource

class Owner {
    val valResource: Resource by ResourceDelegate()
}

class ResourceDelegate {
    operator fun getValue(thisRef: Owner, property: KProperty<*>): Resource {
        return Resource()
    }
}
val readOnlyResource: Resource by resourceDelegate()
var readWriteResource: Resource by resourceDelegate()

fun resourceDelegate(): ReadWriteProperty<Any?, Resource> =
    object : ReadWriteProperty<Any?, Resource> {
        var resource = Resource()
        override fun getValue(thisRef: Any?, property: KProperty<*>) = resource
        override fun setValue(thisRef: Any?, property: KProperty<*>, value: Resource) {
            resource = value
        }
    }