2016-10-19 28 views
2

我試圖做到這一點:是否可以合併漁獲物?

catch LocksmithError.Duplicate, LocksmithError.Allocate {...} 

但我在,得到一個錯誤說:

預期的 '{' 之後 '抓' 的格局

這是否意味着你不能合併案例如case expression2, expression3 :?任何這樣做的理由?

+1

需要停止使用大寫字母作爲案例名稱。 :)這是sooooo 2015. – matt

+1

@matt我們使用框架的Swift 2.3分支。我猜他們的Swift 3版本正在使用更新的召喚 – Honey

+1

哦,不!所以我們仍然在2015年。帶着繩子帶回迪斯科和電話。 :))))) – matt

回答

4

不,這是目前無法多個模式在catch條款相結合 - 語法(as detailed by the Swift Language Guide)只允許一個單一的模式來匹配:

追趕子句→捕獲圖案選擇 where子句選擇碼塊

另一種可能的解決方案已經提出,只要你的錯誤枚舉的那些是微不足道的(這LocksmithError似乎是),是使用where子句的結合模式後:

catch let error as LocksmithError where error == .Duplicate || error == .Allocate { 
    // ... 
} 
+0

好的,這是最簡單的解決方法,沒問題。我要刪除我的答案! – matt

+0

這是預期的還是應該快出來的功能? @matt – Honey

+0

@Honey我不知道你是否打算解決我自己或亞馬遜 - 但我不知道任何圍繞'catch'子句的Swift Evolution討論支持多種模式。正如馬特在他的(現在被刪除的)答案中所說的,如果你願意或者甚至更好的話,你可以在http://bugs.swift.org/上提交一個bug到Swift evolution郵件列表中。 – Hamish

2

既然你讓你的LocksmithError有一些rawvalue類型(例如Int),你可以在一個單一的catch聲明,綁定拋出的錯誤,並使用其rawValue來測試納入的多個錯誤的情況下一個(使用where綁定後的子句)。例如:(!謝謝)

enum FooError: Int, Error { 
    case err1 = 1, err2, err3, err4, err5 
} 

func foo(_ bar: Int) throws { 
    if let err = FooError(rawValue: bar) { throw err } 
} 

func tryFoo(_ bar: Int) { 
    do { 
     try foo(bar) 
    } catch let err as FooError where (1...4).contains(err.rawValue) { 
     print("Any of 1st through 4th error!") 
    } catch FooError.err5 { 
     print("5th error!") 
    } catch {} 
} 

tryFoo(1) // Any of 1st through 4th error! 
tryFoo(4) // Any of 1st through 4th error! 
tryFoo(5) // 5th error! 

至於建議由@ user28434,真的沒有必要應用rawValue剋制同樣的方法上面可以用來direcly看是否綁定err是一個數組的成員給定情況。

enum FooError: Error { 
    case err1, err2, err3 
} 

func foo(_ bar: Int) throws { 
    guard bar != 1 else { throw FooError.err1 } 
    guard bar != 2 else { throw FooError.err2 } 
    guard bar != 3 else { throw FooError.err3 } 
} 

func tryFoo(_ bar: Int) { 
    do { 
     try foo(bar) 
    } catch let err as FooError where [.err1, .err2].contains(err) { 
     print("1st or 2nd error!") 
    } catch FooError.err3 { 
     print("3rd error!") 
    } catch {} 
} 

tryFoo(1) // 1st or 2nd error! 
tryFoo(2) // 1st or 2nd error! 
tryFoo(3) // 3rd error! 

這減少了基本上是一個的the accepted answer變化(對於catch塊上,覆蓋比只有兩個箱子更可能有用,但在這種情況下,有可能錯誤enum應考慮重構)。

+0

所以答案是否定的。但是你提到了一個解決方法。任何理由爲什麼?是否因爲錯誤應該具有一對一的功能? – Honey

+0

@Honey我可以推測這是一個在可能的prio列表上不高的特性,因爲我們可以改進實際catch塊中的模式匹配,如其他答案所示。 – dfri

+0

@downvoter:請考慮提供反饋,爲什麼你認爲這是一個徹頭徹尾的不好答案,我可能會學到一些東西! – dfri

1

這只是一個語法問題,它可能會在Swift 4+中得到改進。

現在你可以使用這個:

catch let locksmithError as LocksmithError { 
    switch locksmithError { 
     case .Duplicate, .Allocate: 
      // your code 
     … 
    } 
} 
+1

@Honey,是的。但是我只是展示了一種如何處理少數幾個枚舉錯誤的方法(?)。所以是的,你可能需要添加一些額外的漁獲量,在開關中的一些額外的情況下,等 – user28434

+0

**評論更新**:如上所述[這裏](http://stackoverflow.com/questions/30826560/swift-2-invalid γ變換-從投擲-函數的類型到非投擲本功能)。你總是需要有一個默認的catch,以防拋出的錯誤是* LocksmithError類型之外的東西,你仍然可以捕獲它。有關詳細信息,請參閱[this]的註釋(http://stackoverflow.com/a/40184140/5175709)回答 – Honey