本文翻译自:What is a sealed trait?
Sealed classes are described in 'Programming in Scala', but sealed traits are not. “Scala编程”中描述了密封类,但密封特性不是。 Where can I find more information about a sealed trait? 我在哪里可以找到有关密封特性的更多信息?
I would like to know, if a sealed trait is the same as a sealed class? 我想知道,如果密封的特性与密封的类相同吗? Or, if not, what are the differences? 或者,如果没有,有什么区别? When is it a good idea to use a sealed trait (and when not)? 何时使用密封特性(何时不是)?
#1楼
参考:https://stackoom.com/question/l0Ts/什么是密封特性
#2楼
From the daily-scala blog : 来自每日scala博客 :
When a trait is "sealed" all of its subclasses are declared within the same file and that makes the set of subclasses finite which allows certain compiler checks. 当特征被“密封”时,它的所有子类都在同一个文件中声明,这使得子类集合有限,允许某些编译器检查。
#3楼
A sealed
trait can be extended only in the same file as its declaration. sealed
特征只能在与其声明相同的文件中扩展。
They are often used to provide an alternative to enums
. 它们通常用于提供enums
的替代方案。 Since they can be only extended in a single file, the compiler knows every possible subtypes and can reason about it. 由于它们只能在单个文件中扩展,因此编译器知道每个可能的子类型并且可以对其进行推理。
For instance with the declaration: 例如声明:
sealed trait Answer
case object Yes extends Answer
case object No extends Answer
The compiler will emit a warning if a match is not exhaustive: 如果匹配不详尽,编译器将发出警告:
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
So you should use sealed traits (or sealed abstract class) if the number of possible subtypes is finite and known in advance. 因此,如果可能的子类型数量是有限的并且事先已知,则应使用密封特征(或密封的抽象类)。 For more examples you can have a look at list and option implementations. 有关更多示例,您可以查看列表和选项实现。
#4楼
a sealed trait is the same as a sealed class ? 密封的特性和密封的一样?
As far as sealed
goes, yes. sealed
去,是的。 They share the normal differences between trait
and class
, of course. 当然,他们分享trait
和class
之间的正常差异。
Or, if not, what are the differences ? 或者,如果没有,有什么区别?
Moot. 没有实际意义。
When is it a good idea to use a sealed trait (and when not) ? 何时使用密封特性(何时不是)?
If you have a sealed class X
, then you have to check for X
as well as any subclasses. 如果你有一个sealed class X
,那么你必须检查X
以及任何子类。 The same is not true of sealed abstract class X
or sealed trait X
. sealed abstract class X
或sealed trait X
。 So you could do sealed abstract class X
, but that's way more verbose than just trait
and for little advantage. 所以你可以做sealed abstract class X
,但这比仅仅trait
和更少的优势更加冗长。
The main advantage of using an abstract class
over a trait
is that it can receive parameters. 使用的主要优点abstract class
在一个trait
是,它可以接收参数。 That advantage is particularly relevant when using type classes. 使用类型类时,这一优势尤为重要。 Let's say you want to build a sorted tree, for instance. 例如,假设您要构建一个排序树。 You can write this: 你可以这样写:
sealed abstract class Tree[T : Ordering]
but you cannot do this: 但你不能这样做:
sealed trait Tree[T : Ordering]
since context bounds (and view bounds) are implemented with implicit parameters. 因为上下文边界(和视图边界)是用隐式参数实现的。 Given that traits can't receive parameters, you can't do that. 鉴于特征无法接收参数,您无法做到这一点。
Personally, I prefer sealed trait
and use it unless some particular reason makes me use a sealed abstract class
. 就个人而言,我更喜欢sealed trait
并使用它,除非某些特殊原因使我使用sealed abstract class
。 And I'm not talking about subtle reasons, but in-your-face reasons you cannot ignore, such as using type classes. 我不是在谈论微妙的原因,而是在面对面的原因,你不能忽视,比如使用类型类。
#5楼
Also I feel the need to point you to the specifications: 另外我觉得有必要指出你的规格:
The sealed modifier applies to class definitions. 密封修改器适用于类定义。 A sealed class may not be directly inherited, except if the inheriting template is defined in the same source file as the inherited class. 密封类可能不会直接继承,除非继承模板在与继承类相同的源文件中定义。 However, subclasses of a sealed class can be inherited anywhere. 但是,密封类的子类可以在任何地方继承。
— M. Odersky. - M. Odersky。 The Scala language specification, version 2.8. Scala语言规范,版本2.8。 online, Sept., 2013. 在线,2013年9月。
#6楼
Briefly: 简述:
- Sealed traits can only be extended in the same file 密封的特征只能在同一个文件中扩展
- List this lets the compiler easily know all possible subtypes 列表这使编译器可以轻松了解所有可能的子类型
- Use sealed traits when the number of possibly subtypes is finite and known in advance 当可能的子类型数量有限且事先已知时,请使用密封特征
- A way of creating something like enum in Java 一种在Java中创建类似枚举的方法
- Help to define algebraic data types (ADTs) 帮助定义代数数据类型(ADT)
and for more details Everything about sealed traits in Scala 以及更多细节关于Scala密封特性的一切