使用泛型类型通过原始值获取枚举中的关联类型

问题描述 投票:0回答:1

这是一个枚举类:

enum class Foo(rawValue: Int) {
    FIRST(1),
    SECOND(2)
}

我可以使用

companion object
通过原始值检索类型:

enum class Foo(rawValue: Int) {
    FIRST(1),
    SECOND(2)


   companion object {
    
      fun getCaseBy(value: Int): Foo? {
        return entries.firstOrNull { it.rawValue == value }
      }
   }
}

然后像这样使用它:

Foo.getCaseBy(1)

有什么方法可以使用泛型类型将这个

getCaseBy
放入
interface
中吗?那么就不需要为每个枚举都添加这样的方法了?

类似:

interface EnumInterface<T> {
    
    companion object {
        
        fun getCaseBy(value: E): T? {
            return T.entries.firstOrNull { it.rawValue == value }
        }
    }
}

enum class Foo(rawValue: Int): EnumInterface(Foo::class) {
    FIRST(1),
    SECOND(2)
}
  1. T
    仅限于
    Enum
    类,
    E
    检索
    T
    的 rawValue 类型。
  2. 只有
    Enum
    类型才能确认此界面
    EnumInterface

这可能吗?

kotlin generics enums
1个回答
0
投票

您可以通过反射来实现。

import kotlin.reflect.full.hasAnnotation
import kotlin.reflect.full.memberProperties

@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.RUNTIME)
annotation class Key

inline fun <reified E : Enum<E>> getValue(enumObject: E): Any? {
  val field = E::class.memberProperties.first { it.hasAnnotation<Key>() }
  return field.get(enumObject)
}

inline fun <reified E : Enum<E>> getValueBy(value: Any?): E {
  return enumValues<E>().first { getValue<E>(it) == value }
}

enum class Foo(@Key val rawValue: Int) {
  FIRST(1),
  SECOND(2);
}

fun main() {
  println(getValueBy<Foo>(2));
}

由于枚举类可以有多种属性名称,因此使用注释

Key
来标记用于比较的属性。

请注意,如果没有注释任何属性,

getValue
将抛出
NoSuchElement
错误。

© www.soinside.com 2019 - 2024. All rights reserved.