处理多个对象实例的最佳方法

时间:2017-11-30 21:14:35

标签: kotlin data-class

部分原因是我无法在Kotlin中创建没有参数的数据类,我使用object来表示这些情况,例如

sealed class Node {
  object Leaf : Node()
  data class Branch(val left:Node, val right:Node) : Node()
}

问题是,有时候,我最终得到了Leaf类的多个实例。显然,这通常不会发生,但是在使用某些框架和某些测试用例进行序列化和反序列化时会发生这种情况。

现在,您可能会争辩说我应该修复这些情况,但很难知道它们的位置,并且不总是可能或不希望修改框架的反序列化语义。

因此,我希望我的object所有实例都充当相同的值,就像无参数data class那样(或无参数{{ Scala中的1}}。

到目前为止,我的最佳解决方案是以下内容,包含在我可能会遇到此问题的每个case class创建中:

object

显然,这是冗长且容易出错的,因为似乎不可能将这些实现抽象出来。超级类可以在对象不需要扩展另一个类的情况下工作,但通常情况并非如此。

或者,我可以使用object SaneLeaf { override fun hashCode() = javaClass.hashCode() override fun equals(other: Any?) = other?.javaClass == javaClass } 参数创建数据类。但这似乎更像是黑客攻击。

其他人如何处理这个问题?是否有计划将NothinghashCode实现添加到遵循这些类的假定语义的对象(所有实例应该是相同/相同的hashCode)?

1 个答案:

答案 0 :(得分:4)

我认为拥有object基础类的多个实例确实是一个你应该解决的问题,但是有一个更简单的解决方法,它允许你拥有你描述的相等语义。 / p>

您可以定义一个执行相等逻辑的抽象类,并使sealed类继承它,如下所示:

abstract class SingletonEquality {
    override fun equals(other: Any?): Boolean =
        this::class.objectInstance != null && other?.javaClass == this.javaClass || 
        super.equals(other)

    override fun hashCode(): Int = 
        if (this::class.objectInstance != null) 
            javaClass.hashCode() else 
            super.hashCode()
}

用法:

sealed class Node : SingletonEquality() {
    object Leaf : Node()
    data class Branch(val left:Node, val right:Node) : Node()
}

此处,Leaf将继承equals的{​​{1}}实施,并按照您想要的方式进行比较。