使用Retrofit,我正在獲取資料并JSONObject使用這樣的結構,例如:
{
"token": "some-token",
"tiles": [
{
"id": "id-1",
"type": "RedTile",
"title": "This red title",
"stuff": "hello world"
},
{
"id": "id-2",
"type": "BlueTile",
"title": "This blue title",
"value": 200
}
]
}
現在,當我得到這個回應時,我需要創建一個決議器,它實際上會從每個圖塊中獲取型別,并將其與應用程式中已經存在的類匹配。我基本上需要從這個回應中創建一個帶有令牌和圖塊串列的新回應,但在這種情況下,圖塊將反映到應用程式中的實際類。
知道什么是正確的方法嗎?
uj5u.com熱心網友回復:
我不知道您的課程是什么樣的,但假設是這樣的:
sealed interface Tile
data class RedTile(val title: String, val stuff: String) : Tile
data class BlueTile(val title: String, val value: Int) : Tile
然后你可以把它作為回應物件
data class Response (
val token: String,
val tiles: List<TileResponse>
) {
fun getTilesObjects() = tiles.mapNotNull { it.toTile() }
}
data class TileResponse (
val id: String,
val type: String,
val title: String,
val stuff: String? = null,
val value: Int? = null
){
fun toTile() : Tile? {
if (type == "RedTile" && stuff != null) return RedTile(title, stuff)
if (type == "BlueTile" && value != null) return BlueTile(title, value)
return null
}
}
然后您可以呼叫toTile()單個TileResponse物件或通過getTilesObjects()對回應物件執行操作來獲取完整串列
uj5u.com熱心網友回復:
因為您在問題的標題中提到了反射:
import kotlin.reflect.full.declaredMemberProperties
data class TileResponse(val id: String, val type: String, val title: String, val stuff: String? = null, val value: Int? = null)
data class Response(val token: String, val tiles: List<Tile>)
sealed interface Tile
data class RedTile(val title: String, val stuff: String) : Tile
data class BlueTile(val title: String, val value: Int) : Tile
fun getTiles(): List<Tile> {
return tileResponses
.filter { tileResponse -> mapTypeToClass.containsKey(tileResponse.type) }
.map { tileResponse ->
val clazz = mapTypeToClass[tileResponse.type]!!
val constructor = clazz.constructors.first()
val declaredMemberProperties = tileResponse::class.declaredMemberProperties
val fields = constructor.parameters.map { parameter ->
parameter to declaredMemberProperties.first { it.name == parameter.name }
}
val arguments = fields.associate { (parameter, property) ->
parameter to property.call(tileResponse)
}
constructor.callBy(arguments)
}
}
val tileResponses = listOf(
TileResponse("id-1", "RedTile", "This red title", "hello world", null),
TileResponse("id-2", "BlueTile", "This blue title", "null", 200)
)
val mapTypeToClass = mapOf(
"RedTile" to RedTile::class,
"BlueTile" to BlueTile::class,
)
val response = Response("some-token", getTiles())
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/481006.html
上一篇:將浮點數四舍五入到最高
