【问题标题】:koltin enum generic functionkotlin 枚举泛型函数
【发布时间】:2020-10-24 10:13:47
【问题描述】:

当给定枚举的默认值时,我需要一个 Kotlin 函数从字符串中返回一个枚举值。

每个枚举类都有一个 valueOf() 方法,但我追求适用于任何给定枚举类的泛型。

对于我可以做的示例枚举:

enum class Example {
    first,
    second,
    third ;

    companion object {  // Note same exact code also works if not in companion object
        fun valueOrDefault(value: String, default: Example) = try {
            valueOf(value)
        } catch (e: IllegalStateException) {
            default
        }
    }
}

挑战在于如何制作一个通用的。我有代码需要为任何给定的枚举类执行此操作。

问题是我看不到如何编写函数的通用版本。

到目前为止我有:

fun <T: Enum<Any>>valueOrDefault(value: String, default: T): T = try {
     valueOf(value) as T
} catch (e: IllegalStateException) {
    default
}

但是无论我使用什么组合都无法访问valueOf() 方法。我尝试为 T 创建函数和扩展函数,但这没有帮助。可能是 Enum&lt;Any&gt; 的语法不正确......但任何见解都值得赞赏。

【问题讨论】:

    标签: kotlin generics enums


    【解决方案1】:

    您可以使用 Kotlin 提供的内部函数通过名称获取任意 enum class 的值:enumValueOf&lt;T&gt;(name: String)

    因为它需要在编译时从每个调用站点获取类型信息才能找到相应的枚举类,所以它只能应用于reified type parameters in inline functions,所以你必须将这些修饰符添加到你的函数中.

    如果失败,它将抛出 IllegalArgumentException(在 JVM 上)或 IllegalStateException(目前使用 Kotlin/JS),因此要返回默认值,您必须捕获异常。

    生成的代码将是:

    inline fun <reified T: Enum<T>> valueOrDefault(value: String, default: T): T = try {
        enumValueOf(value)
    } catch (e: IllegalArgumentException) {
        default
    } catch (e: IllegalStateException) {
        default 
    }
    

    (runnable demo)

    T: Enum&lt;T&gt; 类型参数是如何限制 enum classes 的:它们都实现了 Enum 接口,提供 self 类型作为类型参数。

    还有另一个内部函数可以从表示enum class 的具体类型参数中获取所有枚举值:enumValues

    另一种不需要reified 类型参数但只能用于Kotlin/JVM 而不能用于其他平台的方法是获取defaultjavaClass.enumConstants 并按名称查找值。

    【讨论】:

    • 一般来说是一个很好的答案。谢谢,关键是'enumValue'。但是,当我尝试它时,一个问题没有解决,即使在 JVM 代码中也是如此。令人惊讶,因为你有一个演示。事实证明,无论是 1.3.X kotlin 还是 Kotlin JS,都需要进行更改才能正常工作。从&lt;reified T: Enum&lt;*&gt;&gt;&lt;reified T: Enum&lt;T&gt;&gt;。请注意,这仍然适用于 JVM 版本 1.4。此外,对于 JS 版本,异常不是 IllegalArgumentException,因为它是 JVM,而是 IllegalStateException,所以我正在测试两者,所以代码是多平台的。请在您的回答中做一些注释,以便我给它打勾
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多