如何解决Swift - 使用通用方法为不同的 <T> 类型实现协议
我有一个 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'
那是因为与
有没有优雅的方法来解决这个问题?我无法为这个问题找到一个优雅的解决方案。也许整个想法很糟糕?我也尝试用 PAT 解决这个问题,但也没有运气。
解决方法
按照您编写的方式,通过遵守协议 Client,您必须实现一个函数 get
,它带有一个通用的、不受约束的参数 T
。在提供的示例实现中,您向泛型参数 T
添加了类型约束,该参数与协议中的函数不匹配。
解决此问题的方法不止一种。请记住,您说过所有实体都将符合 Mockable
,需要对您提供的代码进行最少更改的解决方案是使用协议组合来强制所有参数 T
符合 {{1} }} 和 Decodable
。
Mockable
在您的客户端中,您将完全按照所写的方式实现该功能。
现在,在您的 protocol Client {
func get<T: Decodable & Mockable>(_ url: String) -> Promise<T>
}
中,您可以调用 MockClient
,并且在您的实际实现中,您可以根据需要将 T.mock()
视为 T
。当然,这现在要求即使您的模拟参数符合 Decodable
,但我认为您的模拟参数将相当轻量级,因此这不会成为问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。