【问题标题】:kotlin - class grouping like sealed classkotlin - 像密封类一样的类分组
【发布时间】:2023-02-20 20:03:01
【问题描述】:

客户端可以像这样向服务器请求

{
  "id": 3,
  "value": "string"
}
{
  "id": 3,
  "value": {
    "count" : "1",
    "option" : "3",
  }
}
{
  "id": 3,
  "value": {
    "address" : "1",
    "next" : "3",
  }
}

我想将 3 种值类型分组 string / { "count", "option"} / {"address", "next"}

data class Request(
  val id: Int,
  val value: SealedLikeClass
)

我该如何定义 SealedLikeClass ? 我不知道如何在密封类中包含字符串

【问题讨论】:

  • 您是否正在尝试序列化和反序列化此 JSON?或两者?

标签: kotlin


【解决方案1】:

您可以使用通用 Request<T> 定义密封类层次结构。这会将 T 类型参数限制为您提到的 3 种形式。您可以通过删除 sealed- 关键字来删除此限制。

像这样:

sealed interface Request<T> {
    val id: Int
    val value: T
}

data class StringRequest(override val id: Int, val value: String) : Request<String>

data class Count(val count: String, val option: String)
data class CountRequest(override val id: Int, val value: Count): Request<Count>

data class Address(val address: String, val next: String)
data class AddressRequest(override val id: Int, val value: Address): Request<Address>

实际上,如果您不需要 sealed-限制,您实际上也不需要其他 Request-类。在那种情况下,你可以这样做:

data class Request<T>(val id: Int, val value: T)

val aStringRequest = Request(5, "string")

data class Count(val count: String, val option: String)
val aCountRequest = Request(5, Count("count", "option"))

data class Address(val address: String, val next: String)
val anAddressRequest = Request(5, Address("address", "next"))

【讨论】:

  • 我想如果目标是从网络响应中反序列化 JSON,那么将需要 Request 子类
  • 是的,好点@Joffrey
【解决方案2】:

目前您不能使用现有的原始类型定义密封类。这将需要联合类型,但它们目前在 Kotlin 中不可表示(请参阅https://youtrack.jetbrains.com/issue/KT-13108/Denotable-union-and-intersection-types)。

在您的情况下,value 的可能类型似乎是不相关的,并不真正属于一起。在这种情况下,最好的方法可能是使用基于泛型的方法suggested by @marstran above

如果 value 属性表示可以具有不同形式的特定内容,您可以在 Kotlin 中为该类型创建自己的密封类(可能带有字符串版本的包装器,或更好的东西),然后为您的自定义 JSON 反序列化器添加也可以处理简单字符串的类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多