KotlinのInit, setter, getter

Tue, Jan 5, 2021

Kotlinプログラミングを読んでInit周りのエクササイズが勉強になったのでメモ。

以下クラスを定義しプリントする

1
2
3
4
5
6
7
8
9
class Sword(_name: String) {
    var name = _name
        get() = "The Legendary $field"
        set(value) {
            field = value.toLowerCase().reversed().capitalize()
        }
}
val sword = Sword("Excalibur")
println(sword.name)

結果

1
The Legendary Excalibur

エクスカリバーが逆になってcapitalizeされると思いきやそうならない。 続いて以下を実行。

1
2
sword.name = "Gleipnir"
println(sword.name)

結果

1
The Legendary Rinpielg

今回は逆になって出力された。 以上からクラスのインスタンス化では value が null なので setter が動作しない。 二度目はインスタンスのプロパティにアクセスしたため(name_field に直アクセスしたため) setter が動作し, 入力した単語がリバースされた。

このクラスの初期化, 初期化以降も確実に setter を通すためには以下のようにコードを修正する必要がある。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
class Sword(_name: String) {
    var name = _name
        get() = "The Legendary $field"
        set(value) {
            field = value.toLowerCase().reversed().capitalize()
        }

    init {
        name = _name
    }
}
val sword = Sword("Excalibur")
println(sword.name)
=> The Legendary Rubilacxe

name プロパティに直アクセスする場合, value に直接値が渡されるため setter が起動するが, インスタンス化の場合は_nameが使用されるため name_field が元で動く setter は起動しない。

だと、思う笑

いや、あってるはずなんだけどな….

Kotlin は IDE の補完が強くて書いていて気持ちいいなと思うのでどんどんやっていきたい。 何か手頃な OSS ないかな〜〜