Enum.valueOf在Kotlin

时间:2016-02-27 07:01:09

标签: java enums kotlin

有没有办法在没有反思的情况下在Kotlin中制作这样的作品?

inline fun <reified T : kotlin.Enum<T>> safeValueOf(type: String?): T? {
    return java.lang.Enum.valueOf(T::class.java, type)
}

以下示例由于以下原因而无法编译:

  

inline fun <reified T : kotlin.Enum<T>> safeValueOf(type: kotlin.String?): T?中为T键入参数绑定   不满意:推断类型TestEnum?不是kotlin.Enum<TestEnum?>

的子类型
enum class TestEnum

fun main() {
    val value: TestEnum? = safeValueOf("test")
}

4 个答案:

答案 0 :(得分:11)

如果明确指定类型参数值,则函数有效:

val value = safeValueOf<TestEnum>("test")

原始代码也可以正常工作,但由于类型推断实现中的错误而无效:https://youtrack.jetbrains.com/issue/KT-11218

答案 1 :(得分:5)

碰撞安全解决方案

创建一个扩展名,然后呼叫valueOf<MyEnum>("value")。如果类型无效,您将得到null并必须对其进行处理

inline fun <reified T : Enum<T>> valueOf(type: String): T? {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: IllegalArgumentException) {
        null
    }
}

或者,您可以设置默认值,调用valueOf<MyEnum>("value", MyEnum.FALLBACK),并避免返回空值。您可以扩展特定的枚举,使其默认为自动

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T {
    return try {
        java.lang.Enum.valueOf(T::class.java, type)
    } catch (e: IllegalArgumentException) {
        default
    }
}

或者,如果您想两者都做,则第二个:

inline fun <reified T : Enum<T>> valueOf(type: String, default: T): T = valueOf<T>(type) ?: default

答案 2 :(得分:2)

  

从Kotlin 1.1开始,可以使用enumValues()和enumValueOf()函数以通用方式访问枚举类中的常量:

enum class RGB { RED, GREEN, BLUE }

inline fun <reified T : Enum<T>> printAllValues() {
    print(enumValues<T>().joinToString { it.name })
}

printAllValues<RGB>() // prints RED, GREEN, BLUE

https://kotlinlang.org/docs/reference/enum-classes.html#working-with-enum-constants

答案 3 :(得分:1)

我通常会在枚举中添加以下内容:

class Product(models.Model):

    title = models.CharField(max_length=100)

class Order_item(models.Model):
    
    product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
    quantity = models.PositiveSmallIntegerField(default=0)
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    date_added = models.DateTimeField(auto_now_add=True)

这将打出清晰的电话

companion object {
    fun from(type: String?): TestEnum = values().find { it.name == type } ?: DEFAULT
}

当然可以使它返回null