我需要将字符串转换为Enum值,但是想要一个如果字符串不是枚举则返回null的函数。
enum class Colors{
Red, Green, Blue
}
Run Code Online (Sandbox Code Playgroud)
我可以使用Colors.valueOf(testString),只要testString是value,但是如果它无效则会有一个例外,在这种情况下我希望为null。
因为我经常想要这样做,所以扩展功能将是理想的。但是扩展需要对Colors类进行操作,而不是对Colors类型的对象进行操作。
有人知道怎么写这样的扩展名吗?理想情况下,对于任何枚举类都是通用的。
编写顶层函数很简单,但是我正在寻找一个充当标准“方法”的函数
// instead of
val willGetAnException = Colors.valueOf("Yellow") // standard existing fun
val willGetNull = Colors.valueOrNullOf("Orange") // new fun i seek
Run Code Online (Sandbox Code Playgroud)
理想情况下,它是通用的并且适用于任何枚举
小智 10
你可以使用这样的东西:
inline fun <reified T : Enum<T>> String.asEnumOrDefault(defaultValue: T? = null): T? =
enumValues<T>().firstOrNull { it.name.equals(this, ignoreCase = true) } ?: defaultValue
Run Code Online (Sandbox Code Playgroud)
然后: "Yellow".asEnumOrDefault(Colors.Green)
或者,如果您无法推断出它: "Yellow".asEnumOrDefault<Colors>()
Colors.values().find { it.name == "Yellow" }
Run Code Online (Sandbox Code Playgroud)
您不需要扩展,因为必须在现有对象上调用它们。您需要一个顶级功能。有一个内置的,您可以使用:
/**
* Returns an enum entry with specified name.
*/
@SinceKotlin("1.1")
public inline fun <reified T : Enum<T>> enumValueOf(name: String): T
Run Code Online (Sandbox Code Playgroud)
您可以通过推断类型或显式地调用它:
val a : MyEnumClass = enumValueOf("A")
val b = enumValueOf<MyEnumClass>("B")
Run Code Online (Sandbox Code Playgroud)
但是,此方法不可为空:它会抛出 java.lang.IllegalArgumentException未知值。
但是很容易模仿它的行为,并使其具有顶级功能,可用于可为空的枚举:
inline fun <reified T : Enum<*>> enumValueOrNull(name: String): T? =
T::class.java.enumConstants.firstOrNull { it.name == name }
Run Code Online (Sandbox Code Playgroud)