没有矛盾:class A(x: => Int)
相当于class A(private[this] val x: => Int)
而不是class A(private val x: => Int)
。 private[this]
标记值为instance-private,而没有进一步规范的private-modifier允许从该类的任何实例访问值。
不幸的是,定义case class A(private[this] val x: => Int)
也是不允许的。我认为这是因为case-classes需要访问其他实例的构造函数值,因为它们实现了equals
方法。
不过,你可以实现一个案例类将手动提供的功能:
abstract class MyList[+T]
class MyNode[T](val h: T, t: => MyList[T]) extends MyList[T]{
def getT = t // we need to be able to access t
/* EDIT: Actually, this will also lead to an infinite recursion
override def equals(other: Any): Boolean = other match{
case MyNode(i, y) if (getT == y) && (h == i) => true
case _ => false
}*/
override def hashCode = h.hashCode
override def toString = "MyNode[" + h + "]"
}
object MyNode {
def apply[T](h: T, t: => MyList[T]) = new MyNode(h, t)
def unapply[T](n: MyNode[T]) = Some(n.h -> n.getT)
}
要检查这个代码,你可以尝试:
def main(args: Array[String]): Unit = {
lazy val first: MyNode[String] = MyNode("hello", second)
lazy val second: MyNode[String] = MyNode("world", first)
println(first)
println(second)
first match {
case MyNode("hello", s) => println("the second node is " + s)
case _ => println("false")
}
}
不幸的是,我不知道肯定为什么禁止使用名为val和var的成员。然而,它至少有一个危险:想想case-classes如何实现toString
;调用每个构造函数值的toString
- 方法。这可以(并且在这个例子中)导致价值无限地自我调节。您可以通过将t.toString
添加到MyNode
的toString
-方法来检查。
编辑:的equals
的实施也将带来一个问题,即可能比的toString
的实现(主要用于调试)和hashCode
(这只会导致更高的更严重:阅读克里斯·马丁的评论后碰撞率如果你不能把这个参数考虑在内)。你必须仔细考虑如何实现equals
是有意义的。
对于无限数据结构,案例类糖提供什么价值? 'equals','hashCode','toString'不起作用。而且我不确定我对'unapply'的期望。 – 2014-11-05 04:54:11