跳到主內容

【Kotlin】enum class

宣告1: 最基礎的 neum 使用逗號分開

enum class Direction {
    NORTH, SOUTH, WEST, EAST
}
通常搭配when做狀態或是類型判斷

ps. Kotlin 在 1.6 版本也已經在 when 上支援窮舉 Enum,這讓我們使用 Enum 更方便(在這之前只有 sealed class 能夠在 when 裡面被窮舉。)

when(direction){
  Direction.NORTH -> // todo
  Direction.SOUTH -> // todo
  Direction.WEST 	-> // todo
  Direction.EAST 	-> // todo
}

宣告2: 可輸入參數,並加入companion object function

 常數(參數..), 常數(參數..) 使用逗號分割,最後一個使用分號區隔下方區塊

可加入  companion object function 增加使用靈活度

enum class EDeviceType(val id: String, val label: String) {
    ANDROID("0", "安卓"),
    IOS("1", "iOS");

    companion object {
        fun sortedList(desc: Boolean): List<EDeviceType> {
            return if (desc) {
                entries.sortedByDescending { it.id }
            } else {
                entries.sortedBy { it.id }
            }
        }

        fun ofId(id: String): EDeviceType? {
            return entries.firstOrNull { it.id == id }
        }
    }
}

enum class EUpdateType(val id: String, val label: String) {
    NO_UPDATE("0", "不更新"),
    FORCE_UPDATE("1", "強迫更新"),
    RECOMMEND_UPDATE("2", "建議更新");

    companion object {
        fun sortedList(desc: Boolean): List<EUpdateType> {
            return if (desc) {
                entries.sortedByDescending { it.id }
            } else {
                entries.sortedBy { it.id }
            }
        }

        fun ofId(id: String): EUpdateType? {
            return entries.firstOrNull { it.id == id }
        }
    }
}
// 強迫更新的版號
val forceUpdateVersions = updateVersions.filter {
	EUpdateType.ofId(it.updateType.orEmpty()) == EUpdateType.FORCE_UPDATE 
}

enum class ShowStatus(val id: String, val title: String, private val isPreserve: Boolean = false) {
    // 馬上開播
    TEMP("temp", "馬上開播暫存"),
    ON_AIR("onAir", "馬上開播直播中"),
    PUBLISHED("published", "馬上開播已播出"),
    CANCELED("canceled", "馬上開播前user壓取消"),
    STREAM_ENDED("streamEnded", "馬上開播因斷流觸發停播"),

    // 預約開播
    PRESERVED("preserved", "預約開播已預約", true),
    PRESERVED_ON_AIR("preservedOnAir", "預約開播直播中", true),
    PRESERVED_PUBLISHED("preservedPublished", "預約開播已播出", true),
    PRESERVED_CANCELED("preservedCanceled", "預約開播逾時未開播觸發排程壓取消或user壓刪除", true),
    PRESERVED_STREAM_ENDED("preservedStreamEnded", "預約開播因斷流觸發停播", true),

    // 違規檔次
    BAN("ban", "因違規停播", false);

    fun isPlayable(): Boolean {
        return this == TEMP || this == PRESERVED
    }

    fun isStoppable(): Boolean {
        return this == ON_AIR || this == PRESERVED_ON_AIR
    }

    fun isStopped(): Boolean {
        return this == PUBLISHED || this == PRESERVED_PUBLISHED
                || this == STREAM_ENDED || this == PRESERVED_STREAM_ENDED
    }

    fun isBan(): Boolean {
        return this == BAN
    }

    fun toOnAir(): ShowStatus {
        return if (isPreserve) PRESERVED_ON_AIR else ON_AIR
    }

    fun toPublished(): ShowStatus {
        return if (isPreserve) PRESERVED_PUBLISHED else PUBLISHED
    }

    fun toCanceled(): ShowStatus {
        return if (isPreserve) PRESERVED_CANCELED else CANCELED
    }

    fun toStreamEnded(): ShowStatus {
        return if (isPreserve) PRESERVED_STREAM_ENDED else STREAM_ENDED
    }

    fun isCanceled(): Boolean {
        return this == CANCELED || this == PRESERVED_CANCELED
    }

    fun isCancelable(): Boolean {
        return this == TEMP || this == PRESERVED
    }

    companion object {
        fun ofId(id: String?): ShowStatus = entries.firstOrNull { it.id == id } ?: TEMP

        /**
         * 已開播狀態
         */
        fun ofPublished(): List<ShowStatus> = listOf(
            PUBLISHED, PRESERVED_PUBLISHED, STREAM_ENDED, PRESERVED_STREAM_ENDED,
        )

        /**
         * 開播中狀態
         */
        fun ofOnAir(): List<ShowStatus> = listOf(
            ON_AIR, PRESERVED_ON_AIR,
        )

        /**
         * 待開播狀態
         */
        fun ofTemp(): List<ShowStatus> = listOf(
            TEMP, PRESERVED
        )
    }
}


枚舉常數可以使用相應的方法以及重寫的基底方法來聲明自己的匿名類別。

enum class ProtocolState {
    WAITING {
        override fun signal() = TALKING
    },

    TALKING {
        override fun signal() = WAITING
    };

    abstract fun signal(): ProtocolState
}

fun main() {
    var currentState: ProtocolState = ProtocolState.WAITING
    println("Current state: $currentState")

    currentState = currentState.signal()
    println("Signal received, new state: $currentState")

    currentState = currentState.signal()
    println("Signal received, new state: $currentState")
}

// Current state: WAITING
// Signal received, new state: TALKING
// Signal received, new state: WAITING
enum class IntArithmetics : BinaryOperator<Int>, IntBinaryOperator {
    PLUS {
        override fun apply(t: Int, u: Int): Int = t + u
    },
    TIMES {
        override fun apply(t: Int, u: Int): Int = t * u
    };

    override fun applyAsInt(t: Int, u: Int) = apply(t, u)
}

// PLUS(13, 31) = 44
// TIMES(13, 31) = 403

enum 列舉,取值

EnumClass.valueOf(value: String): EnumClass
EnumClass.entries: EnumEntries<EnumClass> // specialized List<EnumClass>
enum class RGB { RED, GREEN, BLUE }

fun main() {
    for (color in RGB.entries) println(color.toString()) // prints RED, GREEN, BLUE
    println("The first color is: ${RGB.valueOf("RED")}") // prints "The first color is: RED"
}

// RED
// GREEN
// BLUE
// The first color is: RED

參考 :
官方文件 https://kotlinlang.org/docs/enum-classes.html