给定一棵树,其形状如下:
enum Tree
case Node(left: Tree, right:Tree)
case Leaf
是否可以创建一个值n:Node
,使得n.left == n || n.right == n
?val n:Node = Node(n,n)
不起作用,但是否有编译时保证不存在这样的值?对于一般的case类,是否有这样的保证(即a.a==a
可能永远不适用于任何a:A
,其中A
是case类)?
一点额外的上下文:我遇到这个问题是因为我需要知道Tree
s的集合是否形成一个单一的、格式良好的树,并且在某个时候想要检查所述集合是否有任何Node
s引用它们自己。
1条答案
按热度按时间bq3bfh9z1#
有了class(case class也不例外),你就可以急切地计算作为参数传递给构造函数的每个表达式。
lazy
或def
不会有帮助,因为在一天结束时,您必须获得引用,并且在构造函数运行之前无法获得它。在构造函数内部,实际上是你第一次获得对(尚未完全构造的)对象的引用。您必须使用
var
或运行时反射来设置此值:(version with var)
(version with reflection)
如果这不是一个case类,你可以在构造函数的主体中做一些奇怪的事情-如果你自己设置
val
,你可以使用一些逻辑来决定引用来自哪里,并将this
作为引用would be accessible。普通的case类,即使有辅助构造函数,不会让你对在构造函数参数列表中定义的
val
做这样的事情-构造函数参数列表中的值是用你传递给它的值初始化的,没有办法定制它。(甚至默认值也会在调用构造函数之前执行),辅助构造函数不允许您将this
用作除了要调用的对象之外的任何对象(this(this)
导致编译错误)。因此,只要你使用的是普通的case类,让Scala生成
val
s定义,并确保没有人使用vars或反射,它就永远不会发生。