今天在看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

}

}

}

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

查看原文