2016-04-24 53 views
2

综观Scala doc for sealed classes,它说:选择模式匹配的穷举

如果模式匹配的选择器是一个密封类的一个实例,模式匹配的汇编可以发射其诊断出一个警告给定的模式集并非详尽无遗,即在运行时有可能会产生MatchError

我不太明白他们在这段中的意思。我的理解是,如果开关盒没有涵盖所有可能性,那么我们会在编译时发出警告,表示在运行时可能会出现错误。它是否正确?

我觉得很奇怪,因为我们怎么能覆盖switch case中的所有场景?我们必须匹配所有可能的字符串,这是愚蠢的,所以我认为我的理解是不正确的。请有人关心澄清?

回答

3

我觉得很奇怪,因为我们怎么能覆盖开关盒中的所有场景?我们必须匹配所有可能的字串

是的,如果选择的类型是String(除非它不是一个sealed类,因为这是一个斯卡拉的概念,String是一个Java类)。

这仅仅是愚蠢的

号对于字符串,你只需要一个包罗万象的情况下,例如

val x: String = ... 
x match { 
    case "a" => ... 
    case "b" => ... 
    case _ => ... 
} 

是一个详尽的比赛:无论x是,它匹配的案件之一。更有用的是,你可以有:

val x: Option[A] = ... 
x match { 
    case Some(y) => ... 
    case None => ... 
} 

和编译器将意识到即使没有全面的情况下匹配是详尽的。

4

什么段落的意思是,在情况下你有一个固定的层次结构是这样的:

sealed trait Foo 
class Bar extends Foo 
class Baz extends Foo 
class Zab extends Foo 

然后,当你在它的模式匹配,如果你已经尝试匹配的编译器可以推断所有可能的类型延长密封特性,在这个例子:

def f(foo: Foo) = foo match { 
    | case _: Bar => println("bar") 
    | case _: Baz => println("baz") 
    | } 

<console>:13: warning: match may not be exhaustive. 
It would fail on the following input: Zab() 
     def f(foo: Foo) = foo match { 
         ^
f: (foo: Foo)Unit 

注意document的开头说:

封闭类不得直接继承,除非继承的 模板在与继承类相同的源文件中定义。

这是Scala独有的,不能用Java完成。即使在同一文件中声明,Java中的final类也不能被继承。这就是为什么这个逻辑不适用于Scala中的String,这是java.lang.String的别名。编译器警告只能针对符合上述条件的Scala类型发出。

0

通配符允许我们覆盖所有场景。

something match { 
    case one => ... 
    case two => ... 
    case _ => ... 
} 

只要所有其他情况不匹配,就选择它;也就是说,这是默认情况。更多信息here