2012-01-18 48 views
4

當分配具有模式匹配的值時,捕捉MatchError的最佳方式是什麼(最簡潔,最清晰,最習慣)?在val初始化時使用Scala中的模式匹配捕獲MatchError?

例子:

val a :: b :: Nil = List(1,2,3) // throws scala.MatchError 

我迄今發現的最好辦法:

val a :: b :: Nil = try { 
    val a1 :: b1 :: Nil = List(1,2,3) 
    List(a1, b1) 
    catch { case e:MatchError => // handle error here } 

是否有一個慣用的方式做到這一點?

+1

你也可以使用'scala.util.control.Exception'。 – 2012-01-18 10:48:03

+1

預期的行爲是什麼? – missingfaktor 2012-01-18 13:54:54

+2

如果模式匹配分配失敗,是不是'MatchError'就是你想要拋出的東西?否則,我會親自使用其他控制結構以不同的方式處理問題。 – 2012-01-18 17:44:29

回答

6

稍微提高對金正日的解決方案:

val a :: b :: Nil = List(1, 2, 3) match { 
    case x @ _ :: _ :: Nil => x 
    case _ => //handle error 
} 

如果你能提供你會如何處理錯誤的詳細信息,我們可以爲您提供更好的解決方案。

+0

關於處理 - 可能只是拋出一個適當的異常。 – Rogach 2012-01-18 14:14:17

7

爲什麼不乾脆

val a::b::Nil = List(1,2,3) match { 
    case a1::b1::Nil => { 
    a1::b1::Nil 
    } 
    case _ => //handle error 
} 

+1

這仍然是4行,它會在複雜模式匹配中產生荒謬的代碼重複。 – Rogach 2012-01-18 11:31:50

+0

在複雜模式匹配中,使用具有異常的多個賦值將是一個真正的混亂。金的回答是最通俗的。 – Nicolas 2012-01-18 12:00:49

1

下面的錯誤沒有解決,但是避免了(有些;請參閱Nicolas的評論)它。我不知道這對提問者來說是否有趣。

scala> val a :: b :: _ = List(1,2,3) 
a: Int = 1 
b: Int = 2 
+1

如果您的元素少於2個,它不會避免任何操作。 – Nicolas 2012-01-18 14:21:51

0

簡單的解決辦法是這樣的:

List(1, 2, 3) match { 
    case a :: b :: Nil => ..... 
    case _ => // handle error 
} 

我不喜歡匹配兩次,因爲是冗餘的。 只有在確定匹配的情況下才能使用模式匹配的「val」,或者添加try/catch塊。