部分原因是我无法在 Kotlin 中创建没有参数的数据类,因此我object在这些情况下使用 s,例如
sealed class Node {
object Leaf : Node()
data class Branch(val left:Node, val right:Node) : Node()
}
Run Code Online (Sandbox Code Playgroud)
问题是,有时,我最终会得到该类的多个实例Leaf。显然,这种情况通常不会发生,但在使用某些框架和某些测试用例进行序列化和反序列化时会发生。
现在,您可能会说我应该修复这些情况,但很难知道它们可能在哪里,并且并不总是可能或不需要修改框架的反序列化语义。
因此,我希望s的所有object实例都充当相同的值,就像无参数data class(或 Scala 中的无参数case class)一样。
到目前为止,我最好的解决方案如下,包含在object我创建的每个可能遇到此问题的解决方案中:
object SaneLeaf {
override fun hashCode() = javaClass.hashCode()
override fun equals(other: Any?) = other?.javaClass == javaClass
}
Run Code Online (Sandbox Code Playgroud)
显然,这是冗长且容易出错的,因为似乎不可能将这些实现抽象到接口中。在对象不需要扩展另一个类的情况下,超类可以工作,但情况通常并非如此。
或者,我可以创建一个带有Nothing参数的数据类。但这似乎更像是一种黑客行为。
其他人如何处理这个问题?是否计划添加hashCode和equals实现遵循这些类的假定语义的对象(所有实例应该相等/相同的 hashCode)?
我相信拥有 an 底层类的多个实例object确实是一个您应该解决的问题,但是有一个更简单的解决方法,可以让您拥有您所描述的相等语义。
您可以定义一个执行相等逻辑的抽象类并使该类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()
}
Run Code Online (Sandbox Code Playgroud)
以及用法:
sealed class Node : SingletonEquality() {
object Leaf : Node()
data class Branch(val left:Node, val right:Node) : Node()
}
Run Code Online (Sandbox Code Playgroud)
在这里,Leaf将继承equals实现SingletonEquality并按照您想要的方式进行比较。
| 归档时间: |
|
| 查看次数: |
1355 次 |
| 最近记录: |