我想在下面的這個類中參考一個物件:
class HerbData {
object Dill {
const val herbName: String = "This is Dill!"
const val scientificName: String = "Anethum Graveolens"
val dullThumbnail: Int = R.drawable.dill_thumbnail_attr
}
object Peppermint {
val herbName: String = "This is Peppermint!"
}
}
無論如何,我可以通過在 Kotlin 中使用字串來參考該物件嗎?這有點我的意思:
HerbData."Dill".herbname
對于 Kotlin,我找不到關于此主題的任何內容。
uj5u.com熱心網友回復:
宣告一個資料類
data class HerbData (
val scientificName: String,
val dullThumbnail: Int
)
初始化一個可變映射并將資料放入其中
val herbData = mutableMapOf<String, HerbData>()
herbData.put("Dill", HerbData("Anethum Graveolens", R.drawable.dill_thumbnail_attr))
herbData.put("Peppermint", HerbData("Mentha piperita", R.drawable.peppermint_thumbnail_attr))
你現在可以
herbData["Dill"].scientificName
uj5u.com熱心網友回復:
class HerbData {
interface Herb {
val herbName: String
val scientificName: String
}
object Dill : Herb {
override val herbName: String = "This is Dill!"
override val scientificName: String = "Anethum Graveolens"
}
object Peppermint: Herb {
override val herbName: String = "This is Peppermint!"
override val scientificName: String = "Mentha piperita"
}
companion object {
operator fun get(name: String): Herb? {
return HerbData::class
.nestedClasses
.find { it.simpleName == name }
?.objectInstance as? Herb
}
}
}
println(HerbData["Dill"]?.herbName) // Prints: This is Dill!
println(HerbData["Peppermint"]?.scientificName) // Prints: Mentha piperita
println(HerbData["Pepper"]?.herbName) // Prints: null
uj5u.com熱心網友回復:
另一種方法是使用列舉類。在地圖的好處是,你有一個資料結構,你可以在代碼中直接參考,因此您可以使用HerbData.Dill以及HerbData["Dill"]。這將使您能夠利用編譯時檢查和 lint 警告、重構、詳盡的模式匹配、代碼完成等,因為資料是在您的代碼中定義的
enum class HerbData(
val herbName: String,
val scientificName: String? = null,
val dullThumbnail: Int? = null
) {
Dill("This is Dill!", "Anethum Graveolens", R.drawable.dill_thumbnail_attr),
Peppermint("This is Peppermint!");
companion object {
operator fun get(name: String): HerbData? =
try { valueOf(name) } catch(e: IllegalArgumentException) { null }
}
}
fun main() {
// no guarantee these lookups exist, need to null-check them
HerbData["Peppermint"]?.herbName.run(::println)
// case-sensitive so this fails
HerbData["peppermint"]?.herbName.run(::println)
// this name is defined in the type system though! No checking required
HerbData.Peppermint.herbName.run(::println)
}
>> This is Peppermint!
null
This is Peppermint!
Enum 類有一個valueOf(String)方法可以讓你按名稱查找常量,但如果沒有匹配項,它會拋出例外。我將它添加為類的get運算子函式,因此您可以使用典型的 getter 訪問,如地圖(例如HerbData["Dill"])。作為替代方案,您可以做一些更整潔的事情:
companion object {
// storing all the enum constants for lookups
private val values = values()
operator fun get(name: String): HerbData? =
values.find() { it.name.equals(name, ignoreCase = true) }
}
您可以調整效率(我只是存盤該values()呼叫每次創建一個新陣列的結果),但這非常簡單 - 您只需存盤所有列舉條目并根據名稱創建查找。如果需要,這可以讓你更聰明一點,比如讓查找不區分大小寫(這可能是也可能不是一件好事,取決于你為什么這樣做)
這里的優點是您自動生成查找 - 如果您重構列舉常量的名稱,字串標簽將始終匹配它(您可以使用列舉常量本身的name屬性獲取它)。當然,代碼中的任何“Dill”字串都將保留為“Dill”——這是使用硬編碼字串查找的限制
真正的問題是,你為什么要這樣做?如果它是純資料,不需要在代碼中顯式參考任何專案,并且它們都在運行時查找,那么您可能應該使用資料類和映射,或者類似的東西。如果您確實需要在編譯時將它們作為代碼中的物件參考(并且嘗試使用HerbData."Dill".herbName意味著您這樣做),那么列舉是一種相當簡單的方法,可以讓您同時做到
uj5u.com熱心網友回復:
你可以直接使用 HerbData.Dill.herbName
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/407626.html
標籤:
上一篇:拆分線僅獲得兩條拆分線
下一篇:沒有正則運算式的有效用戶名
