Добавление свойства к существующему перечислению в Kotlin - PullRequest
0 голосов
/ 04 октября 2018

Учитывая следующее перечисление, определенное во внешнем 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 голосов
/ 05 октября 2018

Вы можете добавить свойства / методы расширения к сопутствующему объекту 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
        ...
    }
}
0 голосов
/ 04 октября 2018

Если вы не используете поле, которое уже существует в исходном перечислении (например, порядковый номер), вы не сможете делать то, о чем просите, не помещая внешнее перечисление в собственное перечисление.

Конечно, вы можете использовать порядковый номер, но более новая версия внешнего 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}")
        }
    }
}

Затем вы можете преобразовать Status в MyStatus с помощью MyStatus.fromStatus (...).Или вы можете добавить функцию расширения в Status, чтобы легко конвертировать в MyStatus.

fun Status.toMyStatus() = MyStatus.fromStatus(this)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...