2016-10-25 22 views
2

我有一組大於5的Enum類,它的值中包含String參數,我想爲所有這些Enum類從JSON對象中的字符串字段進行轉換得到簡單的代碼。如何爲一組Enum類寫一個可重用的字符串轉換爲Enum值? (Kotlin)

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可以工作,以及它的定義是,以及如何實現它枚舉值實例。有什麼建議?

更新:我現在已經寫過這個轉換器。這是最好的方法嗎?我是否也可以表示返回值是參數的子類型,因此不需要轉換返回值?

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}") 
} 
+0

對不起,也許愚蠢的問題,但什麼是一個問題,使用'如果(enumval.toString()== STR)'? –

+0

這是真的 - 只要我決定像這樣覆蓋toString,我不需要使用任何'JsonStringConvertible'或類似的東西。 – user3175580

+0

嗨,看到你的更新。很高興能以某種方式幫助你。根據你更新的問題,你可以在這裏查看,以瞭解如何從'class'參數返回泛型類型:http://stackoverflow.com/questions/34122450/how-to-get-type-in​​fo-for-a-generic - 參數 –

回答

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找出如何更有效地做到這一點。

+0

謝謝。我在這裏得到了很多。我在宗教構造函數中使用了'val jsonStr:String'。有錯誤「'jsonStr'隱藏超類型的成員...」。不知道爲什麼它需要「覆蓋」修飾符。我想我只是分開了'重寫'是必需的。順便說一句,你有沒有想過如何擺脫浮動函數,並寫它是類擴展或類似的東西? – user3175580

+0

@ user3175580你是什麼意思的「浮動功能」? – miensol

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 
} 
相關問題