我有正常的Scala类我想重构成为一个不可变的case类。由于我需要该类在Set
操作中表现良好,我希望在案例类中提供所有Scala编译器自动生成的方法。我想,我想避免写这些不同的方法; equals
,hashCode
,toString
等,因为这非常容易出错。而且我需要为大量的课程做这个,所以我需要一个通用的解决方案,而不仅仅是一个特定的解决方案异常的快速修复或黑客。
以下是我工作的课程:
class Node(val identity: String, childrenArg: List[Node], customNodeArg: CustomNode) {
val children: List[Node] = childrenArg
val customNode: CustomNode = customNodeArg
}
如您所见,类的构造函数有三个参数。第一个是identity
,它是一个只读属性。其余两个childrenArg
和customNodeArg
只是一个常规方法参数;即它们仅在构造实例期间出现,然后在类构造函数执行完成后从类实例中完全消失(除非另外捕获)。
我第一次尝试将此转换为不可变的案例类就是这样(只是从第一个参数中删除val
):
class Node(identity: String, childrenArg: List[Node], customNodeArg: CustomNode) {
val children: List[Node] = childrenArg
val customNode: CustomNode = customNodeArg
}
然而,这导致childrenArg
和customNodeArg
参数的不良影响现在被提升为(只读)属性(而不是将它们保留为常规方法参数)。这会产生进一步的不良影响,将它们包含在编译器生成的equals
和hashCode
实现中。
如何标记不可变案例类的构造函数参数childrenArg
和customNodeArg
,以便identity
是案例类的唯一只读属性?
对此有任何指导;答案,网站讨论链接等,非常感谢。
答案 0 :(得分:1)
第二个参数列表似乎可以解决问题:
scala> trait CustomNode
defined trait CustomNode
scala> case class Node(identity: String)(childrenArg: List[Node], customNodeArg: CustomNode)
defined class Node
scala> val n = Node("id")(Nil, null)
n: Node = Node(id)
scala> n.identity
res0: String = id
scala> n.getClass.getDeclaredFields.map(_.getName)
res1: Array[String] = Array(identity)
答案 1 :(得分:0)
Case类参数默认为val,但您可以将它们设置为vars。
case class Node(identity: String, var childrenArg: List[Node], var customNodeArg: CustomNode)
制作vars会自动为你提供吸气剂和固定器