1

考虑两个类 A 和 B:

// A.scala
object A {
  sealed abstract class Nat
  case object Zero extends Nat
  case class Succ(n : Nat) extends Nat

  def pp(n : Nat) = n match {
    case Zero => println("Zero")
    case Succ(m) => println("Succ")
    case _ => println("WTF")
  }

  def main(args : Array[String]) = 
    pp(B.f())
}
// B.java
public class B {
    static A.Nat f() {
        return new A.Nat() {};
    }
}

编译,运行:

$ scala A
WTF

正如文档中所说,“除非继承模板与被继承的类在同一源文件中定义,否则不能直接继承密封类。”

我认为这意味着通过在同一文件中定义的子类进行模式匹配足以涵盖所有情况,但正如我们从这个示例中看到的那样,这不是真的。

这是一个问题:有没有办法编写真正密封的类(如ADTs)或者我需要在每个模式匹配中编写虚拟的最后一个案例以确保代码安全?

4

1 回答 1

4

可以从 Java 创建它们,因为 Scala 类被密封的细节仅由 Scala 编译器本身提供。Java 编译器根本没有 A.Nat 是密封的概念。

另外作为旁注,您需要将 Succ 标记为已密封,否则即使在 Scala 中也有人可以扩展它。

于 2013-08-08T16:44:39.780 回答