[Scala随用随学] —— sealed声明的作用

今天在看MLlib的源码时,看到Vector的声明是sealed trait,很好奇这个sealed有什么作用,与是搜到了这个文章:

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

试验了下,这个sealed就是保证你在match的时候需要把所有可能出现的情况都写出来。如果漏掉一个,就会报编译出错:

比如下面的代码,声明了两个trait,其中Test2是sealed声明:

sealed trait Test2{}
trait Test1{}

case class A1 extends Test1{}
case class B1 extends Test1{}
case class C1 extends Test1{}

case class A2 extends Test2{}
case class B2 extends Test2{}
case class C2 extends Test2{}

然后做个测试:

object TraitTest {
  def main(args: Array[String]) {
    val x:Test1 = new B1()
    x match {
      case x @ A1() => println("A1")
      case x @ B1() => println("B1")
    }
  }
}

这样是没什么问题的。

object TraitTest1 {
  def main(args: Array[String]) {
    val x:Test2 = new B2()
    x match {
      case x @ A2() => println("A2")
      case x @ B2() => println("B2")
//      case x @ C2() => println("C2")
    }
  }
}

如果注释没有打开,就会报下面的错误:

 Warning:(30, 5) match may not be exhaustive.
      It would fail on the following input: C2()
      x match {
      ^

在Spark MLlib中,它是这样用的:

sealed trait Vector extends Serializable {
...

override def equals(other: Any): Boolean = {
    other match {
      case v2: Vector =>
        if (this.size != v2.size) return false
        (this, v2) match {
          case (s1: SparseVector, s2: SparseVector) =>
            Vectors.equals(s1.indices, s1.values, s2.indices, s2.values)
          case (s1: SparseVector, d1: DenseVector) =>
            Vectors.equals(s1.indices, s1.values, 0 until d1.size, d1.values)
          case (d1: DenseVector, s1: SparseVector) =>
            Vectors.equals(0 until d1.size, d1.values, s1.indices, s1.values)
          case (_, _) => util.Arrays.equals(this.toArray, v2.toArray)
        }
      case _ => false
    }
  }

}

这样能有效的避免遗漏可能出现的情况!

posted @ 2017-06-28 19:13  xingoo  阅读(1552)  评论(0编辑  收藏  举报