2016-04-24 54 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