Answers:
一个sealed
特质只能在同一个文件作为其声明中被延长。
它们通常用于提供替代enums
。由于它们只能在单个文件中扩展,因此编译器知道每种可能的子类型并可以对此进行推理。
例如声明:
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
over 的主要优点trait
是它可以接收参数。使用类型类时,这一优势特别重要。假设您要建立一个排序树。您可以这样写:
sealed abstract class Tree[T : Ordering]
但是您不能这样做:
sealed trait Tree[T : Ordering]
因为上下文范围(和视图范围)是使用隐式参数实现的。鉴于特征无法接收参数,因此您不能这样做。
我个人更喜欢sealed trait
并使用它,除非某些特殊原因使我使用sealed abstract class
。我并不是在说些微妙的原因,而是在谈论您无法忽略的表面原因,例如使用类型类。
[A: F]
)与方差约束的工作方式不同。相反,它是语法糖,它要求F[A]
范围内的隐式。它通常用于召唤类型类实例,该方法比隐式参数((implicit fa: F[A])
)有点更易读,但在幕后仍然可以使用完全相同的方法,而且正如Daniel指出的那样,特质并不需要那。
当特征被“密封”时,其所有子类都在同一文件中声明,这使得子类集变得有限,从而允许某些编译器检查。
另外,我觉得有必要向您指出规格:
该密封 MODI网络呃适用于类去连接nitions。甲密封类可以不直接继承,但如果继承模板是相同的源文件作为继承的类中定义德网络连接。但是,密封类的子类可以在任何地方继承。
ief简而言之:
以及更多详细信息, 有关Scala中密封特征的一切