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