scala中的sealed

scala中的sealedsealed关键字在scala的集合和模式匹配上面应用较多,本篇文章说明sealed的使用场景以及为什么使用sealed。Asealedclasscannothaveanynewsubclassesaddedexcepttheonesinthesamefile.这是sealed关键字比较官方的解释,意思是只在同一个文件中的添加其子类,除此以外不能有任何的子类(区别…

sealed关键字在scala的集合和模式匹配上面应用较多,本篇文章说明sealed的使用场景以及为什么使用sealed。

A sealed class cannot have any new subclasses added except the ones in the same file.这是sealed关键字比较官方的解释,意思是只在同一个文件中的添加其子类,除此以外不能有任何的子类(区别于java中任何类都可以进行集成操作),从这一点可以看出,其主要作用是用于设计上的,但是也有功能上的,下面从设计和功能两方面进行说明。

1. 防止滥用继承

sealed关键字可以修饰类和特质(特质)密封类提供了一种约束:不能在类定义的文件之外定义任何新的子类。这样可以防止继承的滥用,示例如下:

scala源码中List的实现用到了sealed关键字,抽象类List有sealed关键字修饰,在Nil::两个操作中,分别继承了该List的抽象类。当我们实现自己的list集合时,进行继承,将会出现错误。

抽象类List有sealed关键字修饰,接下来Nil和::分别继承了该List抽象类。那我们来尝试实现基于List实现一个自己的List:

scala> class NewList extends List
<console>:7: error: illegal inheritance from sealed class List
       class NewList extends List123

该类在编译的时候就不能通过,我们是不能在外部文件继承List类。所以,如果子类都明确的情况下,这是最为重要的前提,为了防止继承滥用,为抽象类添加sealed。(这一点主要是设计上的作用,在java语言中只有yes 和 no,在scala中提出更为重要的you should use it correctly rather than freely


2. 模式匹配校验子类

模式匹配是scala非常好用的一个语法特性。pattern使用的场景总结起来大约以下几类:

- Wildcard patterns // _ 统配 - Constant patterns // 常量 - Variable patterns // 变量 - Constructor patterns // 构造函数 - Sequence patterns // 比如List(,). 如果需要匹配剩余的话使用List(0,_*) - Tuple patterns // (a,b,c) - Typed patterns // 使用类型匹配 case a:Map[,] - asInstanceOf[] - isInstanceOf[] - note(dirlt):这里需要注意容器类型擦除.Array例外因为这个是java内置类型

但是,当我们频繁改变条件,我们可能会忘了修改相应的case,那么这种情况就可能会出现错误。看下边例子:

scala> :pas
// Entering paste mode (ctrl-D to finish)
  abstract class People
  case object American extends People
  case object Japanese extends People
  case object Chinese extends People
  case object Russia extends People

  def people(p: People) = p match {
    case American ⇒ println("American person")
    case Japanese ⇒ println("Japanese person")
    case Chinese ⇒ println("Chinese person")
  }

// Exiting paste mode, now interpreting.

defined class People
defined object American
defined object Japanese
defined object Chinese
defined object Russia
people: (p: People)Unit

scala> people(American)
American person

scala> people(Russia)
scala.MatchError: Russia (of class Russia$)
  at .people(<console>:13)
  ... 33 elided12345678910111213141516171819202122232425262728293031

这时我们为People加上sealed,当我们编译代码时得到了一个警告:

<console>:18: warning: match may not be exhaustive.
It would fail on the following input: Russia

多温馨的一个提示啊。事情都不是绝对的,如果确定people只处理美国,日本,中国人,编译时总是给这么个警告也挺闹心。能破吗?可定能,看代码:

  def people(p: People) = (p: @unchecked) match {
    case American ⇒ println("American person")
    case Japanese ⇒ println("Japanese person")
    case Chinese ⇒ println("Chinese person")
  }

3. sealed总结

给我个人的感觉,这个关键字主要是在设计上的限制,更加规范你的代码,使你的代码更加的优雅,当然最后要对本文参考如下三篇博客,表示感谢!

https://blog.csdn.net/ZCF1002797280/article/details/50848487

https://www.cnblogs.com/rollenholt/p/4192758.html

https://yq.aliyun.com/articles/8611

今天的文章scala中的sealed分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/7585.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注