查看Scala doc for sealed classes,它说:
如果模式匹配的选择器是密封类的实例,则模式匹配的编译可以发出警告,诊断出给定的一组模式并非详尽无遗,即可能存在{{1}在运行时被提升。
我不太明白他们在这一段中的含义。我的理解是,如果一个switch case没有涵盖所有可能性,那么我们将在编译时收到警告,说我们可能在运行时遇到错误。它是否正确?
我觉得很奇怪,因为我们怎样才能涵盖切换案例中的所有场景?我们必须匹配所有可能的字符串,这只是愚蠢的,所以我认为我的理解是不正确的。有人想解释一下吗?
答案 0 :(得分: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的开头说:
密封类可能不会直接继承,除非继承 template在与继承类相同的源文件中定义。
这是Scala独有的,不能用Java完成。即使在同一文件中声明,Java中的final
类也不能继承。这就是为什么这个逻辑不适用于Scala中的String
,它是java.lang.String
的别名。只有符合上述条件的Scala类型才会发出编译器警告。
答案 1 :(得分:3)
我觉得很奇怪,因为我们怎样才能涵盖切换案例中的所有场景?我们必须匹配所有可能的字符串
是的,如果选择器的类型为sealed
(除了它不是String
类,因为它是一个Scala概念,而val x: String = ...
x match {
case "a" => ...
case "b" => ...
case _ => ...
}
是一个Java类。
这只是愚蠢的
没有。对于字符串,您只需要一个包罗万象的案例,例如:
x
是一个详尽的匹配:无论val x: Option[A] = ...
x match {
case Some(y) => ...
case None => ...
}
是什么,它都匹配其中一个案例。更有用的是,您可以:
Document doc = Jsoup.parse(html);
String postTitle = doc.select("h1.post-title").first().html();
String postContent = doc.select("div.post-content").first().html();
并且即使没有一个包罗万象的情况,编译器也会意识到匹配是详尽无遗的。
答案 2 :(得分:0)
通配符允许我们覆盖所有场景。
something match {
case one => ...
case two => ...
case _ => ...
}
只要所有其他情况不匹配,就会选择它;也就是说,这是默认情况。更多信息here。