简体   繁体   English

如何实现一个通用协议,它具有一个使用关联类型的函数?

[英]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.

相关问题 如何使用关联类型解析协议中的泛型属性? - How to resolve generic property in protocol with associatedtype? 如何要求泛型类型使用协议中的特定类型实现通用协议 - How to require a generic type implement a generic protocol using a specific type in the protocol 以关联类型作为参数类型的 Swift 协议 - Swift protocol with associatedtype as a parameter type 使用关联的类型/类型别名时,类型“ X”不符合协议“ Y” - Type 'X' does not conform to protocol 'Y' when using associatedtype / typealias 斯威夫特:使用通用类型associatedtype segfaults编译器的实例 - Swift: using instance of a generic type associatedtype segfaults compiler 协议只能用作通用约束,因为它具有 Self 或 associatedType 要求 - Protocol can only be used as a generic constraint because it has Self or associatedType requirements 如何使用通用约束类型属性实现Swift协议? - How do I implement a Swift protocol with a generic constrained type property? 返回在 swift 协议 function 中查看相关类型 - return View in swift protocol function with associatedtype 是否有关于使用 `=` 和 `:` 的 Swift 协议关联类型的信息? - Is there information somewhere on Swift protocol associatedtype using `=` versus `:`? 如何实现与另一个类同名的协议 - How to implement a protocol which has same name as another class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM