密封类在“Scala编程”中有描述,但密封特征没有。 我在哪里可以找到更多关于密封性状的信息?
我想知道,一个封闭的特质和一个封闭的职业是否相同? 或者,如果不是,有什么不同? 什么时候使用密封trait是一个好主意(什么时候不是)?
密封类在“Scala编程”中有描述,但密封特征没有。 我在哪里可以找到更多关于密封性状的信息?
我想知道,一个封闭的特质和一个封闭的职业是否相同? 或者,如果不是,有什么不同? 什么时候使用密封trait是一个好主意(什么时候不是)?
当前回答
此外,我觉得有必要向您指出规格:
密封修饰符应用于类定义。密封类不能直接继承,除非继承模板定义在同一个源代码中 文件作为继承的类。但是,密封类的子类可以在任何地方继承。 ——奥德斯基。Scala语言规范,2.8版。2013年9月。
其他回答
来自daily-scala博客:
当一个trait被“密封”时,它的所有子类都在 同一个文件,这使得子类的集合是有限的 某些编译器检查。
密封trait只能在与其声明相同的文件中扩展。
它们通常用于提供枚举的替代方案。由于它们只能在单个文件中扩展,所以编译器知道每一种可能的子类型,并可以进行推理。
例如声明:
sealed trait Answer
case object Yes extends Answer
case object No extends Answer
如果匹配不是穷尽的,编译器会发出警告:
scala> val x: Answer = Yes
x: Answer = Yes
scala> x match {
| case No => println("No")
| }
<console>:12: warning: match is not exhaustive!
missing combination Yes
因此,如果可能的子类型的数量是有限的并且预先知道,那么您应该使用密封的特征(或密封的抽象类)。要获得更多示例,您可以查看列表和选项实现。
一个封闭的特质和一个封闭的职业是一样的吗?
就封存而言,是的。当然,他们在性格和阶级上都有正常的差异。
或者,如果不是,有什么不同?
没有实际意义。
什么时候使用密封trait是一个好主意(什么时候不是)?
如果你有一个密封类X,那么你必须检查X以及任何子类。对于封闭的抽象类X或封闭的特征X,情况就不一样了,所以你可以做封闭的抽象类X,但这比trait要啰嗦得多,也没有什么好处。
与trait相比,使用抽象类的主要优点是它可以接收参数。在使用类型类时,这种优势尤其相关。比方说,你想要构建一棵排序树。你可以这样写:
sealed abstract class Tree[T : Ordering]
但你不能这样做:
sealed trait Tree[T : Ordering]
因为上下文边界(和视图边界)是用隐式参数实现的。考虑到trait不能接收参数,你不能这样做。
就我个人而言,我更喜欢使用密封的trait,除非有特定的原因让我使用密封的抽象类。我不是在谈论微妙的原因,而是您不能忽视的直接原因,例如使用类型类。
此外,我觉得有必要向您指出规格:
密封修饰符应用于类定义。密封类不能直接继承,除非继承模板定义在同一个源代码中 文件作为继承的类。但是,密封类的子类可以在任何地方继承。 ——奥德斯基。Scala语言规范,2.8版。2013年9月。
简要:
密封特征只能在同一个文件中扩展 列表可以让编译器很容易地知道所有可能的子类型 当可能的子类型数量有限且事先知道时,使用密封性状 一种在Java中创建枚举的方法 帮助定义代数数据类型(adt)
想了解更多细节 Scala中关于密封特征的一切