Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Enums kotlin从字符串到枚举的安全转换_Enums_Kotlin - Fatal编程技术网

Enums kotlin从字符串到枚举的安全转换

Enums kotlin从字符串到枚举的安全转换,enums,kotlin,Enums,Kotlin,我需要将字符串转换为枚举值,但需要一个函数,如果字符串不是枚举,则返回null enum class Colors{ Red, Green, Blue } 我可以使用Colors.valueOf(testString),前提是testString是value,但如果它无效,则会出现异常,在这种情况下,我希望为null 因为我想经常这样做,扩展函数将是理想的。但是扩展需要对类颜色进行操作,而不是对类型为Colors的对象进行操作 有人知道如何编写这样的扩展吗?理想情况下,对于任何枚举类

我需要将字符串转换为枚举值,但需要一个函数,如果字符串不是枚举,则返回null

enum class Colors{
   Red, Green, Blue

} 
我可以使用Colors.valueOf(testString),前提是testString是value,但如果它无效,则会出现异常,在这种情况下,我希望为null

因为我想经常这样做,扩展函数将是理想的。但是扩展需要对类颜色进行操作,而不是对类型为Colors的对象进行操作

有人知道如何编写这样的扩展吗?理想情况下,对于任何枚举类都是泛型的

编写顶级函数很简单,但我正在寻找一个像标准“方法”一样的函数

// instead of 
val willGetAnException = Colors.valueOf("Yellow") // standard existing fun
val willGetNull = Colors.valueOrNullOf("Orange")  // new fun i seek

理想情况下,它是通用的,适用于任何枚举,您不需要扩展,因为它们必须在现有对象上调用。您需要一个顶级函数。您可以使用内置的:

/**
 * Returns an enum entry with specified name.
 */
@SinceKotlin("1.1")
public inline fun <reified T : Enum<T>> enumValueOf(name: String): T

您可以使用以下内容:

inline fun <reified T : Enum<T>> String.asEnumOrDefault(defaultValue: T? = null): T? =
    enumValues<T>().firstOrNull { it.name.equals(this, ignoreCase = true) } ?: defaultValue
inline fun String.asEnumOrDefault(defaultValue:T?=null):T=
enumValues().firstOrNull{it.name.equals(this,ignoreCase=true)}?:defaultValue
然后:
“黄色”.asEnumOrDefault(Colors.Green)


或者,如果无法推断:
“Yellow”.asEnumOrDefault()

鉴于在Kotlin中安全访问枚举值并不容易,我发布了一个库来提供一组速记函数,使您可以编写如下代码:

类示例{
枚举类方向(val-az:Int){
北(0),,
东(90),
南部(180),
西(240)
}
fun printAz01(名称:String=“EAST”){
val方向=EnumValuerFull(名称)?:direction.EAST
println(“az01=${direction.az}”)
}
fun printAz02(名称:String=“EAST”){
val direction=name.toEnumOrNull()?:direction.EAST
println(“az02=${direction.az}”)
}
趣味打印名称01(az:Int=0){
val方向=EnumValuerNull{
it.az==az
}?方向:北
println(“name03=${direction.name}”)
}
趣味printName02(序号:Int=0){
val方向=EnumValuerNull{
it.ordinal==序数
}?方向:北
println(“name03=${direction.name}”)
}
}

使用它,不仅可以使用名称访问枚举值,还可以将任意高阶函数作为谓词子句传递。当您需要处理自定义转换(如JPA属性转换器)时,这非常方便。

Kotlin API不能简单地使用
。它抛出类型为
InvocationTargetException
的异常。因此,我通过参数直接传递给
type:Class

Colors.values().find { it.name == "Yellow" }


谢谢这也是我想说的重点。。。。。如果我将该函数设为类的伴生对象的方法(并去掉泛型),我可以按我所希望的方式调用它。如果您希望它仅限于单个枚举类,您可以在伴生对象中添加方法,该方法使用try-catch块包装
valueOf
。谢谢。。。这也是我要说的重点。一个顶级函数,这不是我想要的。有点进一步。。。。。如果我将该函数作为enum类的伴生对象的方法(并去掉泛型),我可以按我所希望的方式调用它。但是如何将泛型方法应用于所有enum类的伴生对象是我所希望的,口头解释通常是有用的这是一个非常简单和优雅的解决方案,不需要扩展函数。您还可以使用Elvis运算符定义默认值:Colors.values()。查找{it.name==“Yellow”}?:Colors.Red
inline fun <reified T : Enum<T>> String.asEnumOrDefault(defaultValue: T? = null): T? =
    enumValues<T>().firstOrNull { it.name.equals(this, ignoreCase = true) } ?: defaultValue
Colors.values().find { it.name == "Yellow" }
private fun <T> enumValueOf(type: Class<T>, enum: String) : T {
    return type.enumConstants.first { it.toString() == enum }
}
if (type.isEnum) enumValueOf(#Field.type, value as String)