什么是密封特质?

密封的类在“Scala编程”中有描述,但是密封的特性不是。 我在哪里可以find关于密封特性的更多信息?

我想知道,如果一个密封的特性是一个密封的类相同? 或者,如果不是,有什么区别? 什么时候使用密封特质是什么时候?

sealed特性只能在其声明的同一个文件中扩展。

他们经常用来提供一个替代enums 。 由于它们只能在一个文件中扩展,所以编译器知道每一个可能的子types,并且可以推理它。

例如声明:

 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 

所以如果可能的亚型数目是有限的并且事先已知的话,你应该使用密封的特征(或密封的抽象类)。 对于更多的例子,你可以看看列表和选项的实现。

一个密封的特质和密封的一样是一样的吗?

至于sealed去,是的。 当然,他们分享traitclass之间的正常差异。

或者,如果不是,有什么区别?

没有实际意义。

什么时候使用密封特质是什么时候?

如果你有一个sealed class X ,那么你必须检查X以及任何子类。 sealed abstract class Xsealed trait X 。 所以你可以做一个sealed abstract class X ,但是这种方法比trait更加冗长,而且没有什么优势。

在特征上使用abstract class的主要优点是可以接收参数。 这个优点在使用types类时尤其重要。 比方说,你想build立一个sorting的树。 你可以写这个:

 sealed abstract class Tree[T : Ordering] 

但是你不能这样做:

 sealed trait Tree[T : Ordering] 

因为上下文边界(和视图边界)是用隐式参数实现的。 鉴于特征不能接收参数,你不能这样做。

就个人而言,我更喜欢sealed trait并使用它,除非某些特定的原因使我使用sealed abstract class 。 我不是在谈论微妙的原因,而是你不能忽视的面子,比如使用types类。

从每日Scala博客 :

当一个特征被“密封”时,所有的子类都被声明在同一个文件中,并且这个子类的集合是有限的,这允许某些编译器检查。

另外我觉得需要指出你的规格:

密封的修改器适用于类定义。 除非inheritance模板被定义在与inheritance类相同的源文件中,否则不能直接inheritance密封类。 但是,密封类的子类可以在任何地方inheritance。

– M. Odersky。 Scala语言规范,版本2.8。 在线,2013年9月。