【问题标题】:How to specify a typeclass for data classes in Kotlin如何在 Kotlin 中为数据类指定类型类
【发布时间】:2020-04-08 05:21:48
【问题描述】:

scala 中,支持case class 的父类是product:因此我们可以将其用于case classees 的多态性。 kotlin中的data classes如何实现类似的目标?

对于下面的yaml 解析器,我需要替换dataclass,它代表所有data classes 的合理父类。

inline fun <reified T: dataclass> loadFromFileDC(path: Path): T  = loadFromFile(path, T::class)

 fun <T: dataclass> loadFromFile(path: Path, cls: KClass<T>) = {
    val mapper = ObjectMapper(YAMLFactory()) // Enable YAML parsing
    mapper.registerModule(KotlinModule()) // Enable Kotlin support

    Files.newBufferedReader(path).use {
        mapper.readValue(it, cls.java)
    }
}

【问题讨论】:

  • 如果我理解正确,我认为在 Kotlin 中是不可能的。您不能从数据类继承,因此无法告诉“这是一个父级,我希望它的所有子级都是数据类”。
  • @MichaelSpitsin data clases 没有他们的自己的继承层次结构/父类可以作为他们的代理吗?如果这些接口代表核心 data class 行为,即使扩展一些 interfaces 也可能有效。
  • 没有。数据类只是普通类,有一堆预定义的方法,如“equals”、“hashCode”等。也就是说你可以从密封类、接口、任何开放或抽象类继承数据类,但没有数据类特定的层次结构据我所知。
  • 嗯。我原以为它们是kotlin 相当于case class。不幸的是,看起来不是。他们甚至没有实现serializable,这让我大吃一惊。我对它们的用处持怀疑态度。
  • @MIchaelSpitsin btw 随意回答。仅仅因为它不是我更喜欢的答案,所以它同样是一个有效的答案。

标签: kotlin typeclass


【解决方案1】:

如果我理解正确,我认为在 Kotlin 中是不可能的。数据类只是普通的类。因此,您可以从任何开放/抽象类、接口或密封类继承它。同时,没有办法从数据类继承,例如,强制所有的孩子都是数据类。并且没有特定于数据类的继承,因为正如我所提到的,数据类只是一个普通类,具有预定义和预生成的一堆方法。

我认为这也值得思考:你真的需要在编译时将每个传递的类识别为数据类吗?为什么你真的需要它?

例如,如果您想应用任何类型的多态性,那么您可以使用的只是equals/hashCode/toString,因为componenNcopy 函数只是生成并且没有他们可以覆盖的基本函数。

因为每个类都可以实现这 3 种方法。您所能做的就是强制实施它们。例如:

interface DataClass {
    override fun equals(other: Any?): Boolean
    override fun hashCode(): Int
    override fun toString(): String
}

data class Impl(val t: Int) : DataClass

在这种情况下,很可能会强制实现为数据类,或者强制提供所有 3 个所需的方法。但这是 hack 而不是实际的解决方案,您将无法将其应用于 3rd-party-classes,因为您将无法使用此界面标记它们。

总结:我建议您考虑一下您是否真的需要知道,是您的示例data class 中的clz,或者它可以是任何东西。如果是,那么您可以考虑使用反射。

请看这个:Is there a way to identify a Kotlin data class from a regular Kotlin class?

【讨论】:

  • 它们不是“普通的类”,因为它们不支持继承。是的,问题在于生成数据类的第三方库,而不是相同的扩展。我试图找到一个通用的解决方案来解决 - 难以置信 - data classes 没有实现 Serializable 的问题。使用kotlinx.serializable 是一个额外的负担,实际上现在甚至无法正常工作。
猜你喜欢
  • 1970-01-01
  • 2018-04-04
  • 2012-05-13
  • 2016-10-16
  • 1970-01-01
  • 1970-01-01
  • 2021-02-27
相关资源
最近更新 更多