読者です 読者をやめる 読者になる 読者になる

2016/12/22の30分 Kotlinメモ🎲

2016/12/22の30分 Kotlinメモ🎲

書いてるコードは雑にここにあります。

github.com

Kotlinスタートブック -新しいAndroidプログラミング を引き続き読んでる。

Kotlinスタートブック -新しいAndroidプログラミング

Kotlinスタートブック -新しいAndroidプログラミング

Properties and Fields

kotlinlang.org

プロパティはあくまで窓口であり、実際に値を保持するBacking Fieldにはプロパティ内部でしかアクセスできないと。

Backing Field = 実際の値の参照を保持するもの?みたいな?

class Person {

    var name: String = ""
        set(value) {
            println("set $value")
            // field = バッキングフィールドを表す暗黙の変数
            field = value
        }
    var age: Int = 0
}

以下のnameLengthプロパティはBacking Fieldは生成されない。

class Person {

    var name: String = ""
        set(value) {
            println("set $value")
            // field = バッキングフィールドを表す暗黙の変数
            field = value
        }
    var age: Int = 0
    val nameLength: Int
        get() = name.length
}

Javaをやってて、プロパティ謎いぞ!フィールドと何が違うの!ってなったけど、@sys1yagiさんが書いてる以下を読んだら納得できた。

バッキングフィールド?なんだそれ?となったら、読んでみるとよい。

5. プロパティの正体 · Anatomy Kotlin

Late-Initialized Properties

kotlinlang.org

Backing Fieldを持つプロパティは必ず初期化する必要があるけど、lateinitをつければ初期化タイミングを遅らせることができるよ!ってことらしい。

使用できるプロパティに色々制限はあるので、用途は限られそう。

class Person {
    // 初期化のタイミングを遅らせる
    // varでしか使えない + non nullでしか使えない + primitiveには使えない + custom getter/setterは持てない
    // https://kotlinlang.org/docs/reference/properties.html#late-initialized-properties
    // DIとかに使える
    // 初期化する前にアクセスするとUninitializedPropertyAccessExceptionが起きる
    lateinit var humuhumu: String
}

val p = Person()
//    println(p.humuhumu) // kotlin.UninitializedPropertyAccessException: lateinit property humuhumu has not been initialized
p.humuhumu = "humuhumu"
println(p.humuhumu) // humuhumu

まとめ

プロパティの謎が少しずつわかってきたのでたのしいたのしい🎲