什么是密封性状?


332

密封的类在“在Scala中编程”中进行了描述,但是密封的特征没有。在哪里可以找到有关密封性状的更多信息?

我想知道,密封特征是否与密封类相同?或者,如果没有,有什么区别?什么时候使用密封特性(什么时候不使用)是个好主意?

Answers:


472

一个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

因此,如果可能的子类型的数量是有限的并且事先已知,则应该使用密封特性(或密封抽象类)。有关更多示例,您可以查看列表选项实现。


112
我花了六个月的时间才能随机到达这里,并了解如何在Scala中替换Java Enum。
sscarduzio 2014年

非常好 !并且不仅是有限且事先已知的,而且是受限(密封的)上下文的一部分,在该上下文中可以检查所有可能的子类型,例如yes | 不,甚至 奇怪的等等...
马里奥·德·萨·维拉

90

密封的特质与密封的类相同吗?

就目前sealed而言,是的。当然,它们共享trait和之间的正常差异class

或者,如果没有,有什么区别?

模拟。

什么时候使用密封特性(什么时候不使用)是个好主意?

如果您有一个sealed class X,那么您必须检查X以及所有子类。sealed abstract class X或并非如此sealed trait X。因此,您可以这样做sealed abstract class X,但这比仅仅冗长trait且无济于事的方式更加冗长。

使用abstract classover 的主要优点trait是它可以接收参数。使用类型类时,这一优势特别重要。假设您要建立一个排序树。您可以这样写:

sealed abstract class Tree[T : Ordering]

但是您不能这样做:

sealed trait Tree[T : Ordering]

因为上下文范围(和视图范围)是使用隐式参数实现的。鉴于特征无法接收参数,因此您不能这样做。

我个人更喜欢sealed trait并使用它,除非某些特殊原因使我使用sealed abstract class。我并不是在说些微妙的原因,而是在谈论您无法忽略的表面原因,例如使用类型类。


“因为上下文边界(和视图边界)是使用隐式参数实现的。” -您能详细说明吗?
Ruby

@Ruby –回复很晚,但是如果您或其他任何人感兴趣:上下文边界([A: F])与方差约束的工作方式不同。相反,它是语法糖,它要求F[A]范围内的隐式。它通常用于召唤类型类实例,该方法比隐式参数((implicit fa: F[A]))有点更易读,但在幕后仍然可以使用完全相同的方法,而且正如Daniel指出的那样,特质并不需要那。
mirichan

54

每日scala博客

当特征被“密封”时,其所有子类都在同一文件中声明,这使得子类集变得有限,从而允许某些编译器检查。


谢谢。“所有子类”意味着类和特征?
约翰·特里普伍德

@John-我还没尝试过,但我怀疑是在上课。关于密封的要点是,一切都在一个源单元中定义
Brian Agnew

1
@JohnThreepwood:类,特征和对象。大多数时候,在Scala中,术语“类”用于指代类,特征和对象。仅在谈论它们之间的特定差异时,它仅表示类。SLS使用术语“模板”来指代类和特征,但是在SLS之外并没有太多使用,并且没有包含所有三个类,特征和对象的术语。
约尔格W¯¯米塔格


7

ief简而言之:

  • 密封特征只能在同一文件中扩展
  • 列出此内容可使编译器轻松知道所有可能的子类型
  • 当可能的亚型数量有限且事先已知时,使用封闭特征
  • 在Java中创建类似枚举的方法
  • 帮助定义代数数据类型(ADT)

以及更多详细信息, 有关Scala中密封特征的一切

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.