Swift 泛型 class 的扩展类型约束,其中泛型是另一种泛型
Swift extension type constraints for generic class where generic type is yet another generic type
我正试图围绕 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
必须是类型 [=23] =] → Result<*, 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))
}
}
您也可以使用协议来做到这一点,但对于枚举,我发现这非常笨拙,因为枚举案例不能被视为符合规范的方法。
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))
}
}
我正试图围绕 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
必须是类型 [=23] =] → Result<*, 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))
}
}
您也可以使用协议来做到这一点,但对于枚举,我发现这非常笨拙,因为枚举案例不能被视为符合规范的方法。
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))
}
}