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