[英]How to implement to a generic protocol, which has a function using the Type of associatedtype?
I am creating some class confirms to a generic protocol, this generic protocol has a method which accept a parameter of the Type of the associatedtype
, I use Xcode to generate the stub for me: 我正在创建一个类确认通用协议,这个通用协议有一个方法接受
associatedtype
类型的类型的参数,我使用Xcode为我生成存根:
import UIKit
struct SomeObject: Codable {
var id: String?
var name: String?
}
protocol INetworkManager {
associatedtype ResponseObject
func get(url: String, ofType: ResponseObject.Type, completion: (ResponseObject?, Error?) -> Void)
}
class NetworkManager: INetworkManager {
typealias ResponseObject = Codable
func get(url: String, ofType: ResponseObject.Protocol, completion: (ResponseObject?, Error?) -> Void) {
completion(SomeObject(id: "1", name: "hello"), nil)
}
}
Instead of ResponseObject.Type
it generates ResponseObject.Protocol
for me, I don't actually know what this ResponseObject.Protocol
is, and I can not pass SomeObject.self
as the parameter like this: 而不是
ResponseObject.Type
它为我生成ResponseObject.Protocol
,我实际上不知道这个ResponseObject.Protocol
是什么,我不能将SomeObject.self
作为参数传递如下:
let networkManager = NetworkManager()
networkManager.get(url: "http://whatever.com", ofType: SomeObject.self) { (responseObject, error) in
print("got response object named: \(responseObject.name)")
}
compiler gave me this error: 编译器给了我这个错误:
error: Cannot convert value of type 'SomeObject.Type' to expected argument type 'NetworkManager.ResponseObject.Protocol' (aka '(Decodable & Encodable).Protocol')
I think something wrong with my implementation, anyone can give me any ideas? 我认为我的实施有问题,任何人都可以给我任何想法?
Thanks! 谢谢!
This isn't how associated types work. 这不是关联类型的工作方式。
get
should be generic over its response type, but the network manager itself isn't generic over some specific response type. get
应该是响应类型的通用,但网络管理器本身并不是某些特定响应类型的通用。 I believe what you meant to here is this: 我相信你在这里的意思是这样的:
protocol NetworkManager {
func get<ResponseObject>(url: String,
ofType: ResponseObject.Type,
completion: (Result<ResponseObject, Error>) -> Void)
where ResponseObject: Decodable
}
class TrivialNetworkManager: NetworkManager {
func get<ResponseObject>(url: String,
ofType: ResponseObject.Type,
completion: (Result<ResponseObject, Error>) -> Void)
where ResponseObject: Decodable {
completion(.success(SomeObject(id: "1", name: "hello"))
}
}
For a more worked-out version of this specific problem you can read my protocol series , but the important concept here is that NetworkManager doesn't vary over its ResponseType, so there's no reason to make its ResponseType an associated type. 对于这个特定问题的更加完善版本,您可以阅读我的协议系列 ,但这里的重要概念是NetworkManager不会因其ResponseType而变化,因此没有理由使其ResponseType成为关联类型。
What you wrote is trying to say "some network managers will have a Codable ResponseType, and other network managers will have some other kind of ResponseType." 你写的是试图说“一些网络管理员会有一个Codable ResponseType,而其他网络管理员会有其他类型的ResponseType。” Not "some other specific response type (like User)" but "some other protocol that its response types would have to conform to."
不是“其他一些特定的响应类型(如User)”,而是“其响应类型必须符合的其他协议”。 While it's conceivable to build something like that, it's much more complex, and you'd need to explain your precise use case in order to design it.
虽然可以想象构建类似的东西,但它要复杂得多,并且您需要解释您的精确用例才能进行设计。 Specifically, you'd need to show several concrete implementations of your protocol in order to see what kind of shared code you're trying to extract.
具体来说,您需要显示协议的几个具体实现,以便查看您尝试提取的共享代码类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.