Scala中的final类和sealed类有啥区别?
Posted
技术标签:
【中文标题】Scala中的final类和sealed类有啥区别?【英文标题】:What are the differences between final class and sealed class in Scala?Scala中的final类和sealed类有什么区别? 【发布时间】:2015-11-18 22:05:52 【问题描述】:Scala 中有两种修饰符:final
和 sealed
它们之间有什么区别?什么时候应该使用一个而不是另一个?
【问题讨论】:
【参考方案1】:sealed
类(或特征)仍然可以在同一个源文件中继承(其中final
类根本不能被继承)。
当您想要限制基类的子类数量时使用sealed
(请参阅“代数数据类型”)。
作为这种限制的非常实际的好处之一,编译器现在可以警告您非详尽的模式匹配:
sealed trait Duo
case class One(i:Int) extends Duo
case class Two(i:Int, j:Int) extends Duo
def test(d:Duo)
match
case One(x) => println(x) // warning since you are not matching Two
【讨论】:
从技术上讲sealed
模板可以在同一个编译单元中扩展,而不是同一个文件。 Scala 编译器的编译单元等于文件这一事实是一个实现细节。可能还有其他编译器使用,例如,数据库来存储源工件而不是文件系统。【参考方案2】:
final
类无法扩展,句号。
sealed
trait 只能在其声明的源文件中扩展。这对于创建 ADT(代数数据类型)很有用。 ADT 由其派生类型的 sum 定义。
例如:
Option[A]
由 Some[A]
+ None
定义。
List[A]
由 ::
+ Nil
定义。
sealed trait Option[+A]
final case class Some[+A] extends Option[A]
object None extends Option[Nothing]
因为Option[A]
是密封的,它不能被其他开发者扩展 - 这样做会改变它的含义。
Some[A]
是最终的,因为它不能被延长,句号。
作为一个额外的好处,如果一个特征是密封的,如果你的模式匹配不够详尽,编译器会警告你,因为它知道Option
是有限到Some
和None
。
opt match
case Some(a) => "hello"
警告:匹配可能并不详尽。它会在以下输入时失败:
None
【讨论】:
从技术上讲sealed
模板可以在同一个编译单元中扩展,而不是同一个文件。 Scala 编译器的编译单元等于文件这一事实是一个实现细节。可能还有其他编译器使用,例如,数据库来存储源工件而不是文件系统。
@JörgWMittag 感谢您的附录,我不知道这种区别。以上是关于Scala中的final类和sealed类有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章