How do I create an enum from a string in Kotlin?

前端 未结 4 1516
情书的邮戳
情书的邮戳 2021-01-03 19:42

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?

相关标签:
4条回答
  • 2021-01-03 19:54

    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())
    }
    
    0 讨论(0)
  • 2021-01-03 20:04

    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")
    }
    
    0 讨论(0)
  • 2021-01-03 20:07

    Would do it like

    enum class MyEnum {
      Foo, Bar, Baz
    }
    
    val value = MyEnum.values().firstOrNull {it.name == "Foo"} // results to MyEnum.Foo
    
    0 讨论(0)
  • 2021-01-03 20:07

    Reusable Exception Safe Solution

    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
    
    0 讨论(0)
提交回复
热议问题