I have an enum with some instances Foo
and Bar
. If I have a string "Foo"
, how can I instantiate a Foo
enum from that? In C# it would be Enum.Parse(...)
, is there an equivalent in Kotlin?
Currently, the best I have found is to create a factory that switches on all possible strings, but that is error prone and performs poorly for large enumerations.
To get an enum constant by its string value, you can use the function valueOf() on the Enum class. It helps us to get enum from a String value in Kotlin.
Use the Enum. IsDefined() method to check if a given string name or integer value is defined in a specified enumeration. Thus, the conversion of String to Enum can be implemented using the Enum. Parse ( ) and Enum.
Create Enumeration of Strings With Extension Function in C# There is no built-in method of declaring an enumeration with string values. If we want to declare an enumeration with string constants, we can use the enum class and an extension function to achieve this goal.
Kotlin enum classes have "static" function valueOf
to get enum entry by string(like Java enums). Additionally they have "static" function values
to get all enum entries. Example:
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())
}
As bashor
suggested, use MyEnum.valueOf()
but please have in mind that it throws an exception if value can't be found. I recommend using:
enum class MyEnum {
Foo, Bar, Baz
}
try {
myVar = MyEnum.valueOf("Qux")
} catch(e: IllegalArgumentException) {
Log.d(TAG, "INVALID MyEnum value: 'Qux' | $e")
}
Would do it like
enum class MyEnum {
Foo, Bar, Baz
}
val value = MyEnum.values().firstOrNull {it.name == "Foo"} // results to MyEnum.Foo
The default solution in Kotlin will throw an exception. If you want a reliable solution that works statically for all enums, try this!
Now just call valueOf<MyEnum>("value")
. If the type is invalid, you'll get null and have to handle it, instead of an exception.
inline fun <reified T : Enum<T>> valueOf(type: String): T? {
return try {
java.lang.Enum.valueOf(T::class.java, type)
} catch (e: Exception) {
null
}
}
Alternatively, you can set a default value, calling valueOf<MyEnum>("value", MyEnum.FALLBACK)
, and avoid a null response. You can extend your specific enum to have the default be automatic
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
}
}
Or if you want both, make the second:
inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T = valueOf<T>(type) ?: default
If you want to create an enum value from one of its parameters, instead of the name, this funny code does a pretty decent job:
inline fun <reified T : Enum<T>, V> ((T) -> V).find(value: V): T? {
return enumValues<T>().firstOrNull { this(it) == value }
}
This can be used like this:
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")
)
This will print Sha256
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With