Swift扩展类型对泛型类的约束,其中泛型类型又是另一个泛型类型

6

我正在努力理解Swift中的泛型类型约束。这是我的起点:

class Promise<T> {
    func resolve(_ block:@escaping (T) ->Void) {}
    func fulfill(_ result:T) {}
}

Promise就是那种可以在未来得以实现的东西。当它与Swift的Result类型一起用于从后台队列返回结果到主队列时,这非常有用:

let promise = Promise<Result<String, Error>>()
promise.fulfill(.success("Hello"))
promise.fulfill(.failure(NSError()))

现在我想为所有使用Result的Promise实例添加扩展,以添加这些辅助方法:

extension Promise where T == Result<X, Error> {
                                    ⬆︎ Here's the problem ⚡️
    func failure(_ error:Error) {
        fulfill(.failure(error))
    }

    func success(_ result:X) {
        fulfill(.success(result))
    }
}

// Shorter:
let promise = Promise<Result<String, Error>>()
promise.success("Hello")
promise.failure(NSError())

唯一的问题是上面的代码无法编译,因为 X 没有定义。我想表达的是:

当泛型类型 T 是类型为 Result<X,Z> 的时候,扩展 Promise,其中 X 可以是任何东西,Z 必须是类型为 Error 的 → Result<*, Error>。这是否可能?

1个回答

7
你想要的是可行的,只是语法稍微有点冗长。你不能将 where 约束条件放在扩展上,而必须将其放在每个方法上。
extension Promise {

    func failure<U>(_ error: Error) where T == Result<U, Error> {
        fulfill(.failure(error))
    }

    func success<U>(_ result: U) where T == Result<U, Error> {
        fulfill(.success(result))
    }
}

你也可以使用协议来实现,但对于枚举类型,我认为这种方式非常笨拙,因为枚举成员无法被视为符合方法。
protocol ResultType {
    associatedtype Success
    associatedtype Failure: Error
    static func makeFailure(_: Failure) -> Self
    static func makeSuccess(_: Success) -> Self
}

extension Result: ResultType {
    static func makeFailure(_ failure: Failure) -> Result<Success, Failure> { .failure(failure)  }
    static func makeSuccess(_ success: Success) -> Result<Success, Failure> { .success(success) }
}

extension Promise where T: ResultType {
    func failure(_ error: T.Failure) {
        fulfill(T.makeFailure(error))
    }

    func success(_ result: T.Success) {
        fulfill(T.makeSuccess(result))
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接