Swift:结果的失败类型不能是协议 - “类型'any ShadowError'不能符合错误”

问题描述 投票:0回答:2

Error
是一种协议,人们能够做到这一点......

let x: Result<Void, Error> = .success(())

ShadowError
符合
Error
并且也是一种协议,但人们无法做到这一点...

protocol ShadowError: Error {}
let x: Result<Void, ShadowError> = .success(()) // FAILS Type 'any ShadowError' cannot conform to Error

因为编译器抱怨这个错误

输入'any ShadowError'不能符合Error

结果失败类型是否有

ShadowError
(或其他
protocol
)?

swift error-handling polymorphism protocols resulttype
2个回答
2
投票

作为协议这是不可能的。您可以将 ShadowError 设为枚举或结构(甚至是包装另一个错误的结构),但它不能是协议。协议存在(协议的“任何”实例)不符合协议,因此

any ShadowError
不是错误。对此有一个神奇的例外:
any Error
确实符合
Error
。但你无法重现它。这只是
Error

有关此内容的文档,请参阅 SE-0235 将结果添加到标准库

作为该提案准备工作的一部分,为错误(并且仅错误)添加了自我一致性。这对于处理一般上下文中的错误通常也很有用。

这种自一致性不会扩展到包括错误协议在内的协议组合,仅扩展到确切类型的错误。将来可以添加此类组合,但这超出了 Swift 5 的范围。


0
投票

您可以像使用自定义结果一样使用它。示例:

enum CustomResult<Result> {
    case success(Result)
    case failure(CustomErrorProtocol)
}

protocol CustomErrorProtocol: Error, LocalizedError {}

struct CustomError: CustomErrorProtocol {

    //it's for external errors, for example from 3rd party libs, errors from native libs etc
    let externalError: Error?

    var errorDescription: String? { return externalError?.localizedDescription ?? "Unknown error"}

    enum SomeServiceError: SnPErrorProtocol {
        case notValid(description: String)
        case dataBase(error: DataBaseError)
    
        var errorDescription: String? {
            switch self {
            case let .notValid(description):
                return description.localized
            case let .dataBase(error):
                return error.localizedDescription
            }
        }
    }

    enum DataBaseError: SnPErrorProtocol {
        case failOnSave
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.