如何在 Kotlin 中从字符串创建枚举?
How do I create an enum from a string in Kotlin?
我有一个枚举,其中包含一些实例 Foo
和 Bar
。如果我有一个字符串 "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
我有一个枚举,其中包含一些实例 Foo
和 Bar
。如果我有一个字符串 "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