如何在一组Enum类中为String to Enum值编写可重用的转换? (科特林)

时间:2016-10-25 06:13:27

标签: enums kotlin

我有一个> gt的Enum类组,它在其值中包含String参数,我想让所有这些Enum类的简单代码从JSON对象中的String字段转换。

enum class Religiousness(val jsonStr: String, val resID: Int) {
    NotAtAll("none", R.string.not_religious),
    Somewhat("somewhat", R.string.somewhat_religious),
    Very("very", R.string.very_religious),
    ;
    override fun toString() = jsonStr
    fun displayString(res: Resources) = res.getString(resID)
}

我希望能够编写像这样的代码

fun JsonConvertStrToEnum(enumClass: Class<Enum<*>>, str: String): Enum<*> {
    for (enumval in enumClass.enumConstants) {
        if ((enumval as IJsonStringConvertible).jsonStr() == str)
            return enumval
    }
    throw IllegalArgumentException("Gave an invalid enum value for class ${enumClass.canonicalName}")
}

我很难弄清楚IJsonStringConvertible是否可以工作,它的定义是什么,以及如何在Enum值实例中实现它。有什么建议吗?

更新:我现在已经将转换器写成了这个。这是最好的方法吗?我是否还可以表示返回值是参数的子类型,因此不需要转换返回值?

fun JsonConvertStrToEnum(enumClass: Class<out Enum<*>>, str: String): Enum<*> {
    for (enumval in enumClass.enumConstants) {
        if (enumval.toString() == str)
            return enumval
    }
    throw IllegalArgumentException("Gave an invalid enum value for class ${enumClass.canonicalName}")
}

2 个答案:

答案 0 :(得分:2)

其他类的枚举可以实现如下接口:

interface IJsonStringConvertible {
    val jsonStr:String
}

enum class Religiousness(override val jsonStr: String, val resID: Int) : IJsonStringConvertible {
    NotAtAll("none", R.string.not_religious),
    Somewhat("somewhat", R.string.somewhat_religious),
    Very("very", R.string.very_religious),
    ;

    override fun toString() = jsonStr
    fun displayString(res: Resources) = res.getString(resID)
}

然后将用作:

for (enumval in enumClass.enumConstants) {
    if ((enumval as IJsonStringConvertible).jsonStr == str)
        return enumval
}

然而,上述查找可能很昂贵(如果使用数百万次)。看看at the reverse lookup question,了解如何更有效地完成它。

答案 1 :(得分:0)

如果它对任何人有帮助,这是最终版本,我认为它可能有效:)

fun <EnumT : Enum<EnumT>> ConvertStrToEnum(enumClass: Class<EnumT>, str: String?): EnumT? {
    if (str == null)
        return null
    for (enumval in enumClass.enumConstants) {
        if (enumval.toString() == str)
            return enumval
    }
    throw IllegalArgumentException("Gave an invalid enum value for class ${enumClass.canonicalName}")
}

fun <EnumT : Enum<EnumT> > ConvertStrArrayToEnumSet(enumClass: Class<EnumT>, array: List<String>?) : EnumSet<EnumT> {
    val set = EnumSet.noneOf(enumClass)
    array?.forEach { value -> set.add(ConvertStrToEnum(enumClass, value)) }
    return set
}