В kotlin, как сделать класс, который отображается с ключами из Enum - PullRequest
0 голосов
/ 17 июня 2019

Или, другими словами, как создать внутреннюю EnumMap внутри моего класса, где типы ключей EnumMap устанавливаются из выбора вызывающего Enum.

Я надеялся получить код вроде:

enum MY_FLAGS { FLAG1, FLAG2, FLAG3 }
val myProfiler = Profiler<MY_FLAGS>()
myProfiler.profile(FLAG1) {
  longRunningOperation() 
  // the time to execute longRunningOperation 
  // is accumulated in myProfiler's EnumMap.
}

У меня есть класс, который отслеживает различные счетчики. Эти счетчики всегда принадлежат одному и тому же классу Enum. Поэтому я хотел бы создать экземпляр класса counter для обработки только этого конкретного Enum.

Пока у меня есть class Profiler<in E:Class<Enum<*>>>(private val clazz: E) {, который кажется действительно близким , но не совсем, потому что, когда я пытаюсь увеличить один из счетчиков с помощью функции класса Profiler, я не могу использовать E !

Например, если бы TempEnum не был жестко закодирован в это:

val enumMap = EnumMap<TempEnum, MutableList<TimeDuration>>(TempEnum::class.java).apply {
  putAll(TempEnum.values().map {
    it to mutableListOf<TimeDuration>()
  })
}

Затем компиляция начинает жаловаться на vs out vs invariant, из-за чего я становлюсь нечетким.

1 Ответ

2 голосов
/ 17 июня 2019

Чтобы создать класс, который может принимать обобщенный Enum в качестве параметра типа, вы можете сделать следующее:

class Profiler<E : Enum<*>> {
   val counter = mutableMapOf<E, Int>()

   fun profile(key: E, block: (E) -> Unit) {
        block(key)
        // increase counter
    }
}

Это можно вызвать с помощью:

fun main() {
    val profiler = Profiler<MyFlags>()
    profiler.profile(MyFlags.Flag2) {
        println("$it - ${profiler.counter[it]}")
    }
}

Чтобы ограничить Profiler только принятием MyFlags в качестве допустимого параметра типа, вы можете изменить сигнатуру класса следующим образом:

class Profiler<E : Enum<MyFlags>> {
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...