向Kotlin中的现有枚举添加属性

时间:2018-10-04 14:40:45

标签: enums kotlin

给出以下在外部api中定义的枚举。

public enum Status {
  COMPLETE,
  RUNNING,
  WAITING
}

我想为每个枚举值添加一个int标志的方法。我知道我可以扩展枚举:

fun Status.flag(): Int {
    when(this) {
        RUNNING -> return 1;
        WAITING -> return 2;
        else -> return 0;
    }
}

但是我想将这些int标志值定义为常量。也许是同伴对象,但我认为我不能扩展现有的枚举并添加同伴对象。

有什么想法吗?

2 个答案:

答案 0 :(得分:0)

除非您使用的是原始枚举中已经存在的字段(如序数),否则如果不将外部枚举包装在您自己的枚举中,您将无法执行所要的操作。

当然可以使用序数,但是较新版本的外部API可能会更改枚举中各项的顺序,因此我不建议这样做。但是,如果您确实想要,可以执行以下操作(同样,不建议这样做):

val Status.flag: Int
    get() = this.ordinal

但是我绝对建议将其包装。这样,您可以保证您定义的标志整数不会更改。

enum class MyStatus(val status: Status, val flag: Int) {
    COMPLETE(Status.COMPLETE, 0),
    RUNNING(Status.RUNNING, 1),
    WAITING(Status.WAITING, 2);

    companion object {
        private val STATUS_TO_MYSTATUS = values().associateBy { it.status }

        fun fromStatus(status: Status): MyStatus {
            return STATUS_TO_MYSTATUS[status] ?: throw Exception("No MyStatus found for status ${status.name}")
        }
    }
}

然后可以使用MyStatus.fromStatus(...)将Status转换为MyStatus。或者,您可以向Status添加扩展功能,以轻松转换为MyStatus。

fun Status.toMyStatus() = MyStatus.fromStatus(this)

答案 1 :(得分:0)

您可以将扩展属性/方法添加到enum / class / etc的伴随对象中。如果存在:

val Status.Companion.COMPLETE_INT = 0
val Status.Companion.RUNNING_INT = 1

但是,实际上,您当前无法“创建”同伴对象。因此,只需将常量放入您自己的非随播对象中即可:

object StatusFlags {
    const val COMPLETE_INT = 0
    const val RUNNING_INT = 1
    const val WAITING_INT = 2
}

fun Status.flag(): Int {
    when(this) {
        RUNNING -> return StatusFlags.RUNNING_INT
        ...
    }
}