scala 什么是密封性状?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11203268/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is a sealed trait?
提问by John Threepwood
Sealed classes are described in 'Programming in Scala', but sealed traits are not. Where can I find more information about a sealed trait?
密封类在“Scala 编程”中进行了描述,但密封特性不是。我在哪里可以找到有关密封特性的更多信息?
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)?
我想知道,密封的特性是否与密封的类相同?或者,如果不是,有什么区别?什么时候使用密封特性是个好主意(什么时候不使用)?
回答by paradigmatic
A sealedtrait can be extended only in the same file as its declaration.
一个sealed特质只能在同一个文件作为其声明中被延长。
They are often used to provide an alternative to enums. Since they can be only extended in a single file, the compiler knows every possible subtypes and can reason about it.
它们通常用于提供enums. 由于它们只能在单个文件中扩展,因此编译器知道所有可能的子类型并可以对其进行推理。
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 listand optionimplementations.
回答by Daniel C. Sobral
a sealed trait is the same as a sealed class ?
密封特性与密封类相同吗?
As far as sealedgoes, yes. They share the normal differences between traitand class, of course.
就目前sealed而言,是的。当然,它们共享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 Xas well as any subclasses. The same is not true of sealed abstract class Xor sealed trait X. So you could do sealed abstract class X, but that's way more verbose than just traitand for little advantage.
如果您有sealed class X,那么您必须检查X以及任何子类。sealed abstract class X或 的情况并非如此sealed trait X。所以你可以这样做sealed abstract class X,但这比仅仅trait而且几乎没有优势的方式更加冗长。
The main advantage of using an abstract classover a traitis that it can receive parameters. 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:
使用abstract classover a的主要优点trait是它可以接收参数。当使用类型类时,这种优势尤其重要。例如,假设您想构建一棵排序树。你可以这样写:
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.
因为上下文边界(和视图边界)是用隐式参数实现的。鉴于 trait 不能接收参数,你不能这样做。
Personally, I prefer sealed traitand use it unless some particular reason makes me use a sealed abstract class. And I'm not talking about subtle reasons, but in-your-face reasons you cannot ignore, such as using type classes.
就个人而言,我更喜欢sealed trait并使用它,除非某些特殊原因让我使用sealed abstract class. 而且我不是在谈论微妙的原因,而是你不能忽视的当面原因,例如使用类型类。
回答by Brian Agnew
From the daily-scala blog:
来自每日斯卡拉博客:
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.
当一个特征被“密封”时,它的所有子类都在同一个文件中声明,这使得子类集是有限的,允许某些编译器检查。
回答by A T
Also I feel the need to point you to the specifications:
此外,我觉得有必要向您指出规格:
The sealedmodi?er applies to class de?nitions. A sealedclass may not be directly inherited, except if the inheriting template is de?ned in the same source file as the inherited class. However, subclasses of a sealed class can be inherited anywhere.
— M. Odersky. The Scala language specification, version 2.8. online, Sept., 2013.
该密封MODI?呃适用于类去?nitions。甲密封类可以不直接继承,但如果继承模板是德?定义相同的源文件作为继承的类英寸 但是,密封类的子类可以在任何地方继承。
回答by Majid Hosseini
??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
- Help to define algebraic data types (ADTs)
- Sealed trait 只能在同一个文件中扩展
- 列出这让编译器很容易知道所有可能的子类型
- 当可能的子类型数量有限且事先已知时,使用密封特征
- 一种在 Java 中创建类似 enum 的方法
- 帮助定义代数数据类型 (ADT)
and for more details Everything about sealed traits in Scala
以及更多细节 关于Scala中密封特征的一切

