ios – 如何使用通用约束类型属性实现Swift协议?

我想有一个看起来像这样的协议:

protocol ReturnType {
    var returnType: ImmutableMappable.Type { get }
}

实现协议的枚举部分:

extension ShimEndPoint: ReturnType {
    var returnType: ImmutableMappable.Type {
        switch self {
        case .deAuthorize(_, _):
            return EmptyResponse.self
        case .authorize(_, _):
            return AuthorizeResponse.self
        case .step(_, _, _, _):
            return StepResponse.self 
        }
    }
}

EmptyResponse,AuthorizeResponse和StepResponse都实现了ImmutableMappable.
现在我想在函数调用中使用“returnType”属性:

return Shim.provider
    .request(endPoint)
    .timeout(7,
             scheduler: MainScheduler.asyncInstance)
    .retry(3)
    .mapObject(endPoint.returnType)

line mapObject给出了以下编译器错误:
“无法将’ImmutableMappable.Type’类型的值转换为预期的参数类型’T.Type’

“mapObject”的函数签名是:

public func mapObject<T : ImmutableMappable>(_ type: T.Type) -> RxSwift.Observable<T>

如何定义和实现协议,以便将returnType传递给mapObject函数?

我发现了一个类似的问题,但不幸的是,在给出的答案的帮助下,我无法解决我的问题:
Returning constrained generics from functions and methods

最佳答案 就个人而言,我觉得你的一些代码真的没有意义.喜欢 :

extension ShimEndPoint: ReturnType {
    var returnType: ImmutableMappable.Type {
        switch self {
        case .deAuthorize(_, _):
            return EmptyResponse.self
        case .authorize(_, _):
            return AuthorizeResponse.self
        case .step(_, _, _, _):
            return StepResponse.self 
        }
    }
}

对象如何根据自身确定自身的类型?然后返回一个与自身不同的值类型?

所以我在这里试图帮助的只是试图找到你想要实现的解决方案,而不是解决现有的代码.

我假设您尝试做的是确定要映射到的对象类型取决于运行时的结果案例.枚举本身是ImmutableMappable,它有3种情况:.authorize,.deauthorize和.step.

函数.request将返回此类型,并根据情况确定要映射到的类型.但是,由于对象的类型需要在编译时确定,所以这里的所有结果类型EmptyResponse,AuthorizeResponse和StepResponse必须遵循相同的协议(我假设,响应在这里),结果也只返回协议而不是特定的班级类型.

return Shim.provider
    .request(endPoint)
    .timeout(7,
             scheduler: MainScheduler.asyncInstance)
    .retry(3)
    .flatMap { result: ImmutableMappable -> Observable<Response> in
       return Observable.create{
        switch result {
          case .authorize:
            observer.onNext(AuthorizeResponse())
          case .deAuthorize:
            //etc
          case step:
            //etc.
           }
        }
     }

希望这能回答你的问题!

点赞