Mar*_*ark 6 generics type-constraints swift swift-extensions
我正在尝试了解 Swift 中的泛型类型约束。这是我的出发点:
\n\nclass Promise<T> {\n func resolve(_ block:@escaping (T) ->Void) {}\n func fulfill(_ result:T) {}\n}\nRun Code Online (Sandbox Code Playgroud)\n\nPromise 就是将来可以实现的事情。当它与 Swift 类型一起使用时,Result将结果从后台队列返回到主队列时,这会变得非常有用:
let promise = Promise<Result<String, Error>>()\npromise.fulfill(.success("Hello"))\npromise.fulfill(.failure(NSError()))\nRun Code Online (Sandbox Code Playgroud)\n\n现在我想向所有用于Result添加这些辅助方法的 Promise 实例添加扩展:
extension Promise where T == Result<X, Error> {\n \xe2\xac\x86\xef\xb8\x8e Here\'s the problem \xe2\x9a\xa1\xef\xb8\x8f\n func failure(_ error:Error) {\n fulfill(.failure(error))\n }\n\n func success(_ result:X) {\n fulfill(.success(result))\n }\n}\n\n// Shorter:\nlet promise = Promise<Result<String, Error>>()\npromise.success("Hello")\npromise.failure(NSError())\nRun Code Online (Sandbox Code Playgroud)\n\n唯一的问题是上面的代码无法编译,因为X没有定义。我想表达的是这样的:
Promise当其泛型类型T为 where 类型Result<X,Z>且X可以是任何内容且必须为\xe2\x86\x92Z类型时进行扩展。这可能吗?ErrorResult<*, Error>
你想要的都是可能的,只是语法有点冗长。您不能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))
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用协议来完成此操作,但对于枚举,我发现这非常笨拙,因为枚举案例不能被视为一致的方法。
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))
}
}
Run Code Online (Sandbox Code Playgroud)