如何在 Kotlin 中从字符串创建枚举?

How do I create an enum from a string in Kotlin?

我有一个枚举,其中包含一些实例 FooBar。如果我有一个字符串 "Foo",我如何从中实例化一个 Foo 枚举?在 C# 中,它将是 Enum.Parse(...),在 Kotlin 中是否有等效项?

目前,我发现的最好的方法是创建一个可以打开所有可能字符串的工厂,但这很容易出错,并且对于大型枚举的性能很差。

Kotlin 枚举 类 具有 "static" 函数 valueOf 以通过字符串获取枚举条目(如 Java 枚举)。此外,他们还有 "static" 函数 values 来获取所有枚举条目。示例:

enum class MyEnum {
  Foo, Bar, Baz
}

fun main(args : Array<String>) {
  println(MyEnum.valueOf("Foo") == MyEnum.Foo)
  println(MyEnum.valueOf("Bar") == MyEnum.Bar)
  println(MyEnum.values().toList())
}

bashor 所建议,使用 MyEnum.valueOf() 但请记住,如果找不到值,它会抛出异常。我推荐使用:

enum class MyEnum {
  Foo, Bar, Baz
}

try {
   myVar = MyEnum.valueOf("Qux")
} catch(e: IllegalArgumentException) {
   Log.d(TAG, "INVALID MyEnum value: 'Qux' | $e")
}

会喜欢

enum class MyEnum {
  Foo, Bar, Baz
}

val value = MyEnum.values().firstOrNull {it.name == "Foo"} // results to MyEnum.Foo

可重复使用的异常安全解决方案

Kotlin 中的默认解决方案会抛出异常。如果您想要一个静态适用于所有枚举的可靠解决方案,请试试这个!

现在打电话给valueOf<MyEnum>("value")。如果类型无效,您将得到 null 并且必须处理它,而不是异常。

inline fun <reified T : Enum<T>> valueOf(type: String): T? {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: Exception) {
        null
    }
}

或者,您可以设置默认值,调用 valueOf<MyEnum>("value", MyEnum.FALLBACK),避免出现空响应。您可以扩展您的特定枚举,使其默认为自动

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: Exception) {
        default
    }
}

或者,如果两者都想要,则制作第二个:

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T = valueOf<T>(type) ?: default

如果您想从它的一个参数而不是名称创建一个枚举值,这个有趣的代码可以做得很好:

inline fun <reified T : Enum<T>, V> ((T) -> V).find(value: V): T? {
    return enumValues<T>().firstOrNull { this(it) == value }
}

可以这样使用:

enum class Algorithms(val string: String) {
    Sha1("SHA-1"),
    Sha256("SHA-256"),
}

fun main() = println(
    Algorithms::string.find("SHA-256")
            ?: throw IllegalArgumentException("Bad algorithm string: SHA-256")
)

这将打印 Sha256