spark scala中的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

    1
    2
    3

该类在编译的时候就不能通过,我们是不能在外部文件继承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内置类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

但是,当我们频繁改变条件,我们可能会忘了修改相应的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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

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

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

    1
    2

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

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

    1
    2
    3
    4
    5

3. sealed总结

给我个人的感觉,这个关键字主要是在设计上的限制,更加规范你的代码,使你的代码更加的优雅,当然最后要对本文参考如下三篇博客,表示感谢!
---------------------  
作者:wangxiaotongfan  
来源:CSDN  
原文:https://blog.csdn.net/wangxiaotongfan/article/details/82348923  
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/a627082796/article/details/87879987
今日推荐