Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

kotlin safe conversion from string to enum

Tags:

enums

kotlin

I need to convert strings to Enum values, but want a function which returns null if the string is not an enum.

enum class Colors{
   Red, Green, Blue

} 

I can used Colors.valueOf(testString) provided testString is value, but there will be an exception if it is not valid, and I want a null in that case.

Because I want to this often, an extension function would be ideal. But the extension needs to operate on the class Colors, and not an object of type Colors.

Anyone know how to write such an extension? Ideally one that is generic for any enum class.

It is simple to write a top level function, but I am seeking one that acts as the standard 'method' does

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

And ideally one that is generic and works for any enum

like image 748
innov8 Avatar asked Aug 02 '18 23:08

innov8


People also ask

Can we convert string to 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. TryParse () method.

How do I get the enum from string in Kotlin?

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.

How do I create an enum from a string?

You can create Enum from String by using Enum. valueOf() method. valueOf() is a static method that is added on every Enum class during compile-time and it's implicitly available to all Enum along with values(), name(), and cardinal() methods.


1 Answers

You don't want an extension since they must be invoked on an existing object. You want a top-level function. There is a built in one You can use:

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

You can call it by inferring the type, or explicitly:

val a : MyEnumClass = enumValueOf("A")
val b = enumValueOf<MyEnumClass>("B")

However this method is not nullable: it throws java.lang.IllegalArgumentException on unknown values.

But it's easy to mimick it's behavior and have it work for nullable enums with a top level function:

inline fun <reified T : Enum<*>> enumValueOrNull(name: String): T? =
    T::class.java.enumConstants.firstOrNull { it.name == name }
like image 193
Pawel Avatar answered Sep 20 '22 05:09

Pawel