【问题标题】:Swift How to returning a tuple from a do catch where conditional binding must have optional type?Swift如何从条件绑定必须具有可选类型的do catch返回元组?
【发布时间】:2018-01-12 10:58:08
【问题描述】:

我想把一个 swift 3 do-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 方面做错了什么,我该如何避免?

谢谢

【问题讨论】:

    标签: swift tuples optional do-catch


    【解决方案1】:

    只需使用可选转换而不是强制转换。即使不使用 if let 语句,使用强制转换结果也会有一个非可选值。

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

    【讨论】:

    • 这将执行从(Bool, Error?)(Bool, Error?) 的尝试转换,即尝试从类型到自身的转换,这将始终成功(如果您在项目中尝试此操作,编译器应该警告你这种情况总是成功的)。因此,这实际上只是将实例分配给属性 (result) 的一种迂回方式,首先将其打包到可选项的 .some(...) 中,然后立即将其解包回具体值。
    【解决方案2】:

    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)")
    }
    

    【讨论】:

    • 明白。我会做出改变并感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2015-09-29
    • 2017-06-28
    • 2018-11-06
    • 1970-01-01
    • 2015-09-11
    相关资源
    最近更新 更多