Issue
I need a Kotlin function to return an enum value from a string when given a default value for the enum.
Each enum class has a valueOf() method, but I am after a generic that works for any given enum class.
For a sample enum I can do:
enum class Example {
first,
second,
third ;
companion object { // Note same exact code also works if not in companion object
fun valueOrDefault(value: String, default: Example) = try {
valueOf(value)
} catch (e: IllegalStateException) {
default
}
}
}
The challenge is how to make a generic. I have code that needs to do this for any given enum class.
The problem is I cannot see how to write a generic version of the function.
So far I have:
fun <T: Enum<Any>>valueOrDefault(value: String, default: T): T = try {
valueOf(value) as T
} catch (e: IllegalStateException) {
default
}
But no matter what combination I use can cannot get access to the valueOf()
method. I tried making the function and extension function for T , but that did not help. It could be that the syntax of Enum<Any>
is incorrect... but any insight appreciated.
Solution
You can use an intrinsic function that Kotlin provides for getting a value of an arbitrary enum class
by name: enumValueOf<T>(name: String)
.
As it needs to get the type information at compile time from each of the call sites in order to find the corresponding enum class, it can only be applied to reified
type parameters in inline
functions, so you will have to add those modifiers to your function.
If it fails, it will throw an IllegalArgumentException
(on the JVM) or IllegalStateException
(with Kotlin/JS as of now), so to return the default value, you have to catch the exception.
The resulting code would be:
inline fun <reified T: Enum<T>> valueOrDefault(value: String, default: T): T = try {
enumValueOf(value)
} catch (e: IllegalArgumentException) {
default
} catch (e: IllegalStateException) {
default
}
The T: Enum<T>
type parameter is how an enum class
es are restricted: they all implement the Enum
interface providing the self type as the type argument.
There's another intrinsic function that gets all enum values from a reified type parameter representing an enum class
: enumValues
Another way that doesn't require reified
type parameters but can only work with Kotlin/JVM but not other platforms is to get the default
's javaClass.enumConstants
and find the value by name.
Answered By - hotkey
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.