Kotlin:如何检查枚举是否包含给定的字符串而不会弄乱异常?

时间:2017-01-25 05:29:00

标签: kotlin

为什么枚举类(以及Java)中没有contains方法?以及如何优雅地实现它?现在我正在使用这种丑陋的方法:

val contains: Boolean = 
    try {
        MyEnum.valueOf("some string")
        true
    } catch (e: IllegalArgumentException) {
        false
    }

3 个答案:

答案 0 :(得分:22)

enumContains

您可以创建enumContains函数,类似于Hound Dog answer但使用reified type parameters代替。

您无法在Kotlin 1.0中创建独立于JVM的解决方案,但您可以使用enumValues在Kotlin 1.1中创建。

Kotlin 1.1

/**
 * Returns `true` if enum T contains an entry with the specified name.
 */
inline fun <reified T : Enum<T>> enumContains(name: String): Boolean {
    return enumValues<T>().any { it.name == name}
}

Kotlin 1.0

/**
 * Returns `true` if enum T contains an entry with the specified name.
 */
inline fun <reified T : Enum<T>> enumContains(name: String): Boolean {
    return T::class.java.enumConstants.any { it.name == name}
}

用法

enumContains<MyEnum>("some string") // returns true or false

enumValueOfOrNull

如果您还需要实际的枚举条目,那么您可以考虑改为创建enumValueOfOrNull函数。

Kotlin 1.1

/**
 * Returns an enum entry with the specified name or `null` if no such entry was found.
 */
inline fun <reified T : Enum<T>> enumValueOfOrNull(name: String): T? {
    return enumValues<T>().find { it.name == name }
}

Kotlin 1.0

/**
 * Returns an enum entry with the specified name or `null` if no such entry was found.
 */
inline fun <reified T : Enum<T>> enumValueOfOrNull(name: String): T? {
    return T::class.java.enumConstants.find { it.name == name }
}

用法

enumValueOfOrNull<MyEnum>("some string")

答案 1 :(得分:5)

您可以只使用values枚举数组并使用包含它。例如:

Planets.values().map { it.name }.contains("EARTH")

但是为此您需要具有正确的字符串值,以便在搜索之前将其置于大写。

如果您想根据其值找到枚举,请查看Reverse Lookup的枚举。

修改

正如@JamesBassett建议你可以优化它,一旦找到匹配就停止寻找。

Planets.values().any { it.name == "EARTH" }

答案 2 :(得分:2)

你可以这样做:

fun <T : Enum<*>> KClass<T>.contains(value: String): Boolean {
    return this.java.enumConstants.any { it.name == value }
}

MyEnum::class.contains("some string")