我有一些实例Foo和枚举Bar.如果我有一个字符串"Foo",我怎么能从中实例化一个Foo枚举?在C#Enum.Parse(...)中,Kotlin会有相同的东西吗?
目前,我发现最好的是创建一个工厂,打开所有可能的字符串,但这容易出错,并且对于大型枚举表现不佳.
bas*_*hor 38
Kotlin枚举类具有"静态"功能valueOf ,可以通过字符串获取枚举(如Java枚举).此外,它们具有"静态"功能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())
}
Run Code Online (Sandbox Code Playgroud)
Nor*_*yer 17
会不会喜欢
enum class MyEnum {
Foo, Bar, Baz
}
val value = MyEnum.values().firstOrNull {it.name == "Foo"} // results to MyEnum.Foo
Run Code Online (Sandbox Code Playgroud)
squ*_*rel 15
如果你想从它的一个属性而不是名称创建一个枚举常量,这个有趣的代码可以完成相当不错的工作:
import kotlin.enums.enumEntries
import kotlin.reflect.KProperty1
@OptIn(ExperimentalStdlibApi::class)
inline fun <reified T : Enum<T>, V> KProperty1<T, V>.findOrNull(value: V): T? =
enumEntries<T>().firstOrNull { this(it) == value }
inline fun <reified T : Enum<T>, V> KProperty1<T, V>.find(value: V): T =
findOrNull(value) ?: throw IllegalArgumentException(
"Could not find enum constant with property `$name` of value `$value`"
)
Run Code Online (Sandbox Code Playgroud)
这些可以像这样使用:
enum class Algorithms(val string: String) {
Sha1("SHA-1"),
Sha256("SHA-256"),
}
fun main() {
// This will print `Sha256`
println(Algorithms::string.findOrNull("SHA-256"))
// This will crash with:
// IllegalArgumentException: Could not find enum constant with property `string` of value `SHA-420`
Algorithms::string.find("SHA-420")
}
Run Code Online (Sandbox Code Playgroud)
如果不使用 Kotlin 1.9.20 或更高版本,请替换enumEntries为效率较低的 enumValues. 这也不需要选择实验性 API。
另请注意,字符串插值会消耗资源并可能导致错误,因此根据您的用例,您可能希望创建自定义参数化异常,或者在构造IllegalArgumentException.
按照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")
}
Run Code Online (Sandbox Code Playgroud)
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
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以设置默认值,调用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
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您想要两者,请制作第二个:
inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T = valueOf<T>(type) ?: default
Run Code Online (Sandbox Code Playgroud)
您可以创建这种枚举类,它将接受一个字符串并将其转换为枚举类型
enum class EmployeeType(val value: String) {
Contractor("CONTRACTOR"),
FullTime("FULL_TIME"),
PartTime("PART_TIME");
companion object {
public fun fromValue(value: String): EmployeeType = when (value) {
"CONTRACTOR" -> Contractor
"FULL_TIME" -> FullTime
"PART_TIME" -> PartTime
else -> throw IllegalArgumentException()
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24206 次 |
| 最近记录: |