#35 Kotlin Koans Properties/Delegates how it works 해설

1 소개



Kotlin 공식 레퍼런스의 Kotlin Koans Properties/Delegates how it works의 해설 기사입니다.

Kotlin Koans를 통해 Kotlin을 배우는 사람들의 도움이 되길 바랍니다.

다만, 레퍼런스를 자력으로 읽는 힘을 기르고 싶은 분은,
곧이 기사를 보지 마십시오!

일단 각자 도전하고 나서 볼 수 있다고 생각합니다

2 Properties/Delegates how it works 설명



Kotlin Koans Properties/Delegates how it works 의 해설입니다.
수시로 본 사이트의 내용을 인용하겠습니다.

본문과 코드를 살펴보자.

You may declare your own delegates . Implement the methods of the class 'EffectiveDate' so it can be delegated to. Store only the time in milliseconds in 'timeInMillis' property.

Use the extension functions MyDate.toMillis() and Long.toDate(), defined at MyDate.kt

Delegates_how_it_works
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

class D {
    var date: MyDate by EffectiveDate()
}

class EffectiveDate<R> : ReadWriteProperty<R, MyDate> {

    var timeInMillis: Long? = null

    override fun getValue(thisRef: R, property: KProperty<*>): MyDate {
        TODO()
    }

    override fun setValue(thisRef: R, property: KProperty<*>, value: MyDate) {
        TODO()
    }
}

MyDate.kt
import java.util.Calendar

data class MyDate(val year: Int, val month:Int, val dayOfMonth: Int)

fun MyDate.toMillis(): Long{
    val c = Calendar.getInstance()
    c.set(year,month,dayOfMonth,0,0,0)
    c.set(Calendar.MILLISECOND,0)
    return c.getTimeInMillis()
}

fun Long.toDate(): MyDate {
    val c = Calendar.getInstance()
    c.setTimeInMillis(this)
    return MyDate(c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DATE))
}

Delegated property에 이용하는 클래스를 자작해, 그 안에 getValue()와 setValue()를 적절히 정의합니다.

처음에 Delegated property date에 값을 사용할 때,

즉 EffectiveDate() 클래스의 getValue()를 이용할 때의 구현을 생각해 봅시다.

timeInMillis 속성을 이용하여 MyDate 인스턴스를 얻고 싶기 때문에 다음과 같습니다.

Delegates_how_it_works
 override fun getValue(thisRef: R, property: KProperty<*>): MyDate {
        return timeInMillis!!.toDate()
 }

(timeInMillis는 null 허용형이므로!! 연산자를 이용하여 강제적으로 비null 허용형으로 변환하고 있습니다.)

다음으로 Delegated property date에 값을 대입할 때,

즉 EffectiveDate() 클래스의 setValue()를 이용할 때의 구현을 생각해 봅시다.

date에 값(MyDate형)을 대입하는 것으로, 밀리 세컨드 단위의 시각을 얻고 싶기 때문에, 이하와 같은 구현이 됩니다.

Delegates_how_it_works
override fun setValue(thisRef: R, property: KProperty<*>, value: MyDate) {
       timeInMillis = value.toMillis()
}

최종 구현은 다음과 같습니다.

Delegates_how_it_works
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

class D {
    var date: MyDate by EffectiveDate()
}

class EffectiveDate<R> : ReadWriteProperty<R, MyDate> {

    var timeInMillis: Long? = null

    override fun getValue(thisRef: R, property: KProperty<*>): MyDate {
        return timeInMillis!!.toDate()
    }

    override fun setValue(thisRef: R, property: KProperty<*>, value: MyDate) {
        timeInMillis = value.toMillis()
    }
}

3 마지막으로



다음은 Kotlin Koans Builders/Function literals with receiver에 대한 설명입니다.

좋은 웹페이지 즐겨찾기