繁体   English   中英

Swift - 用通用方法实现不同的协议<t>类型</t>

[英]Swift - implement protocol with generic method for different <T> types

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

protocol Client {
  func get<T>(_ url: String) -> Promise<T>
}

现在,当我尝试实现它时,问题就开始了。 我想要两种类型的客户端:AlamofireClient 和 MockClient(也许将来会更多,比如 ErrorClient 等,但让我们从简单的开始)

所以我需要类似的东西:

final class AlamofireClient: Client {
   func get<T: Decodable>(_ url: String) -> Promise<T> {
        (...)
   }
}

和:

final class MockClient: Client {
   func get<T: Mockable>(_ url: String) -> Promise<T> {
            return Promise { seal in
               seal.fulfill(T.mock())
        }
   }
}

这里是应用程序中每个实体都将实现的简单 Mockable 接口:

public protocol Mockable {
    static func mock() -> Self
}

但我总是得到错误:

Type 'MockClient' does not conform to protocol 'Client'
Type 'AlamofireClient' does not conform to protocol 'Client'

那是因为与 <T: Decodable> 和 <T: Mockable> 不一样

有没有一种优雅的方法来解决这个问题? 我无法为这个问题找到一个优雅的解决方案。 也许整个想法很糟糕? 我也尝试用 PAT 解决问题,但也没有运气。

您编写它的方式,通过遵守协议客户端,您必须实现一个 function get ,并带有一个通用的、不受约束的参数T 在提供的示例实现中,您向泛型参数T添加了类型约束,它与协议中的 function 不匹配。

有不止一种方法可以解决这个问题。 请记住,您说所有实体都将符合Mockable ,需要对您提供的代码进行最少更改的解决方案是使用协议组合来强制所有参数T符合DecodableMockable

protocol Client {
  func get<T: Decodable & Mockable>(_ url: String) -> Promise<T>
}

在您的客户中,您将完全按照所写的方式实现 function。

现在,在您的MockClient中,您可以调用T.mock() ,并且在您的实际实现中,您可以根据需要将T视为Decodable 当然,现在这要求即使您的模拟 arguments 也符合Decodable ,但我会假设您的模拟 arguments 将相当轻巧,因此这不会成为问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM