Swift如何从条件绑定必须具有可选类型的do catch中返回元组?

Swift如何从条件绑定必须具有可选类型的do catch中返回元组?

问题描述:

我想把一个快速的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方面,我该如何避免它?

谢谢

返回类型从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

只需使用可选铸造,而不是强制铸造。即使没有使用if let语句,使用强制转换结果也将具有非可选值。

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

} 
+0

哦好的,非常感谢 – zardon

+0

这将执行试图从'(Bool,Error?)'转换为'(Bool,Error?)',也就是从一个类型到它自己的尝试转换,它总是会成功的(如果你在你的项目中试用这个,编译器应该警告你,这种情况总是成功的)。因此,这实际上只是一个迂回的方法,通过首先将实例分配到一个可选的'.some(...)'中,然后立即将它解包回到一个具体的值,从而将一个实例分配给一个属性('result')。 – dfri