什么是密封特质?
密封的类在“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
去,是的。 当然,他们分享trait
和class
之间的正常差异。
或者,如果不是,有什么区别?
没有实际意义。
什么时候使用密封特质是什么时候?
如果你有一个sealed class X
,那么你必须检查X
以及任何子类。 sealed abstract class X
或sealed 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月。