1

我想把一个 swift 3do-catch放在一个函数中,而不是在我需要的地方不断地写它;在这个函数中,我希望返回tuple一个布尔值和一个可选错误。

我正在尝试从函数返回一个元组并在我的 XCTest 中处理结果

但是,我收到一条错误消息:

条件绑定的初始化程序必须具有 Optional 类型,而不是 '(Bool, Error?)'(又名 '(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我该如何避免?

谢谢

4

2 回答 2

2

isValidPurchase(train:player)is的返回类型(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)")
}
于 2017-08-04T13:38:47.060 回答
1

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

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

}
于 2017-08-04T13:20:21.140 回答