2016/12/05の30分 Kotlinメモ🌵

2016/12/05の30分 Kotlinメモ🌵

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

github.com

Nested Classes

kotlinlang.org

インナークラスね。そこまでJavaと違いはないかな。

メソッドの中にメソッド定義できるのかー。

class Nest {

    private val a = "a"

    class Test {
        fun test() = "test"

        fun test2(): String {
            // メソッドの中でクラス定義もできる
            class Test3(val s: String) {
            }
            Test3("test").s

            // メソッドもネストしてローカル関数として定義できる
            fun test3(s: String): String {
                return s + " test3"
            }

            return test3("test2")
        }
    }

    // innerをつけると内部クラス
    inner class Test2 {
        fun test() = a
    }
}

Enum

kotlinlang.org

まあ普通のEnumだね。

enum class Status {
    OPEN, RUNNING, CLOSE,
}

enum class Color(val rgb: Int) {
    RED(0xFF0000),
    GREEN(0x00FF00),
    BLUE(0x0000FF)
}

enum class ProtocolState {
    // WAITINGはProtoclStateを継承してsignal()をオーバーライドした無名クラスのインスタンス
    WAITING {
        override fun signal() = TALKING
    },

    TALKING {
        override fun signal() = WAITING
    };

    abstract fun signal(): ProtocolState
}

ほむほむ。名前と位置の情報を持ってるのか。使うのかな?

Every enum constant has properties to obtain its name and position in the enum class declaration

val name: String
val ordinal: Int

println(Color.RED.name) // RED
println(Color.RED.ordinal) // 0

Sealed Classes

kotlinlang.org

taro.hatenablog.jp

クラスの継承を制限するための修飾子?なのかな?

// sealedを付けられたクラスを継承できるのは、その内部クラスだけ
sealed class TaskStatus {
    class New(val id: Long) : TaskStatus()
    class Running(val id: Long, val date: String) : TaskStatus()
    class Close(val id: Long, val close: Boolean) : TaskStatus()
    object None : TaskStatus()
}

whenで使うといい感じなのかな?

状態の表現 + whenという組み合わせて、なんかできそうかも。

fun states(taskStatus: TaskStatus): String = when (taskStatus) {
    is TaskStatus.New -> "new"
    is TaskStatus.Running -> "run"
    is TaskStatus.Close -> "close"
    TaskStatus.None -> "none"
}

val new = TaskStatus.New(0)
val run = TaskStatus.Running(0, "test")
val close = TaskStatus.Close(0, true)
val none = TaskStatus.None

println(states(new)) // new
println(states(run)) // run
println(states(close)) // close
println(states(none)) // none

when式の分岐でelseがない = sealed classとして定義されており、他の場所でそのサブクラスが定義されないことを保証してる。なので、when式の分岐ですべての場合が考慮されていることをコンパイラは知っているのでelseが不要みたいなことがtaroさんのブログに書いてあって、なるほどーとなった。

まとめ

思った以上にenumが普通で残念かなーSwiftみたいな感じがいいなー

Sealed Classesで似たような感じになるのかなー