2017-08-04 59 views
0

我想把一個快速的3 do-catch放在一個函數中,而不是隨時隨地寫在我需要的地方;在這個函數裏我希望返回一個帶有布爾值的tuple,以及一個可選的錯誤。Swift如何從條件綁定必須具有可選類型的do catch中返回元組?

我試圖從函數返回一個元組和處理的結果我XCTest

不過,我得到一個錯誤說:

初始值設定爲有條件的結合必須有可選的類型,而不是' (Bool,Error?)'(aka'(Bool,Optional)')

我的功能如下;

public static func isValidPurchase(train: Train, player: Player) -> (Bool, Error?) { 
    do { 
     let result = try train.canBePurchased(by: player) 
     return (result, nil) 
    } catch let error { 
     return (false, error) 
    } 
} 

canBePurchased代碼是有點長,但它是這樣的:

func canBePurchased(by player: Player) throws -> Bool { 

     if (!self.isUnlocked) { 
      throw ErrorCode.trainIsNotUnlocked(train: self) 
     } 

    // other if-statements and throws go here 
} 

在我XCTest我把它看作:

if let result = TrainAPI.isValidPurchase(train: firstTrain, player: firstPlayer) as! (Bool, Error?) { 

} 

我試着施法力:

if let result: (Bool, Error?) ...

但這隻會將編譯器錯誤降級爲警告。

編譯器顯示如上所述的錯誤。

我在做什麼錯在Initializer for conditional binding must have Optional type方面,我該如何避免它?

謝謝

回答

1

返回類型從isValidPurchase(train:player)(Bool, Error?),這是不可選的(它是其中第二構件恰好是一個可選的元組)。因此,當從呼叫返回到isValidPurchase(train:player)時,沒有用於可選綁定。您只需從那裏分配的返回值,並研究它的內容(可能的錯誤等):

// e.g. using explicitly separate tuple members 
let (result, error) = TrainAPI 
    .isValidPurchase(train: firstTrain, player: firstPlayer) 

if let error = error { /* you have an error */ } 
else { /* no error, proceed with 'result' */ } 

或者,使用switch聲明學習回報:

// result is a tuple of type (Bool, Error?) 
let result = TrainAPI 
     .isValidPurchase(train: firstTrain, player: firstPlayer) 

switch result { 
    case (_, let error?): print("An error occured!") 
    case (let result, _): print("Result = \(result)") 
} 
+0

瞭解。我會做出改變並感謝您的幫助 – zardon

1

只需使用可選鑄造,而不是強制鑄造。即使沒有使用if let語句,使用強制轉換結果也將具有非可選值。

if let result = TrainAPI.isValidPurchase(train: firstTrain, player: firstPlayer) as? (Bool, Error?) { 

} 
+0

哦好的,非常感謝 – zardon

+0

這將執行試圖從'(Bool,Error?)'轉換爲'(Bool,Error?)',也就是從一個類型到它自己的嘗試轉換,它總是會成功的(如果你在你的項目中試用這個,編譯器應該警告你,這種情況總是成功的)。因此,這實際上只是一個迂迴的方法,通過首先將實例分配到一個可選的'.some(...)'中,然後立即將它解包回到一個具體的值,從而將一個實例分配給一個屬性('result')。 – dfri

相關問題