微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

kotlinx.serialization 中的可选字段与空值

如何解决kotlinx.serialization 中的可选字段与空值

如何区分 反序列化 JSON 时 kotlinx.serialization 中的 {data: null}{}

@Serializable
class MyClass(val data: String?)

解决方法

您需要一个自定义的 setter 和一个私有的布尔字段来指示是否触摸了该字段值。所以像:

@Serializable
class MyClass {
    private var isDataTouched = false

    val data: String
        set(value) {        
            field = value
            isDataTouched = true
        }
}

注意,您不能在默认构造函数中定义字段。

,

您可以利用 polymorphismJsonContentPolymorphicSerializer 结合来区分您正在反序列化的响应类型:

@Serializable(with = MyResponseSerializer::class)
sealed class MyResponse

@Serializable
class MyEmptyClass : MyResponse()

@Serializable
class MyClass(val data: String?) : MyResponse()

// this serializer is reponsible for determining what class we will receive
// by inspecting json structure
object MyResponseSerializer : JsonContentPolymorphicSerializer<MyResponse>(MyResponse::class) {
    override fun selectDeserializer(element: JsonElement) = when {
        "data" in element.jsonObject -> MyClass.serializer()
        else -> MyEmptyClass.serializer()
    }
}

使用 MyResponse 类反序列化之后,您将收到 MyEmptyClassMyClass

val e = Json.decodeFromString<MyResponse>("""{}""")             // returns MyEmptyClass object
val o = Json.decodeFromString<MyResponse>("""{"data": null}""") // returns MyClass object

println(Json.encodeToString(e)) // {}
println(Json.encodeToString(o)) // {"data": null}

// since sealed class is the parent we can have exhaustive when:
when(e) {
    is MyClass -> TODO("handle response with data")
    is MyEmptyClass -> TODO("handle empty response")
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。