Protocol只能用作通用约束,因为它具有Self或associatedType的要求 [英] Protocol can only be used as a generic constraint because it has Self or associatedType requirements

查看:1509
本文介绍了Protocol只能用作通用约束,因为它具有Self或associatedType的要求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好我有一个协议的RequestType,它有如下的associatedType Model。

Hi I have a protocol RequestType and it has associatedType Model as below.

public protocol RequestType: class {

    associatedtype Model
    var path: String { get set }

}

public extension RequestType {

    public func executeRequest(completionHandler: Result<Model, NSError> -> Void) {
        request.response(rootKeyPath: rootKeyPath) { [weak self] (response: Response<Model, NSError>) -> Void in
            completionHandler(response.result)
            guard let weakSelf = self else { return }
            if weakSelf.logging { debugPrint(response) }
        }
    }

}

现在我正在尝试对所有失败的请求进行排队。

Now I am trying to make a queue of all failed requests.

public class RequestEventuallyQueue {

    static let requestEventuallyQueue = RequestEventuallyQueue()
    let queue = [RequestType]()

}

但是我收到了错误 let queue = [RequestType]()该协议的RequestType只能用作通用约束,因为它具有Self或associatedType的要求。

But I get the error on line let queue = [RequestType]() that Protocol RequestType can only be used as a generic constraint because it has Self or associatedType requirements.

任何帮助将不胜感激。

推荐答案

假设我们现在调整您的协议以添加一个使用关联的类型:

Suppose for the moment we adjust your protocol to add a routine that uses the associated type:

 public protocol RequestType: class {
     associatedtype Model
     var path: String { get set }

     func frobulateModel(aModel: Model)
 }

Swift让你以你想要的方式创建一个 RequestType 的数组。我可以将这些请求类型的数组传递给一个函数:

And Swift were to let you create an array of RequestType the way you want to. I could pass an array of those request types into a function:

func handleQueueOfRequests(queue: [RequestType]) {
    // frobulate All The Things!

    for request in queue {
       request.frobulateModel(/* What do I put here? */)
    }
}

我开始关注所有事情,但我需要知道传递给调用的参数类型。我的一些 RequestType 实体可以使用 LegoModel ,有些可能需要 PlasticModel ,其他人可以使用 PeanutButterAndPeepsModel 。 Swift对模糊不满并不满意,所以它不会让你声明一个具有关联类型的协议变量。

I get down to the point that I want to frobulate all the things, but I need to know what type of argument to pass into the call. Some of my RequestType entities could take a LegoModel, some could take a PlasticModel, and others could take a PeanutButterAndPeepsModel. Swift is not happy with the ambiguity so it will not let you declare a variable of a protocol that has an associated type.

同时,它非常合理,例如,当我们知道它们都使用 LegoModel 时,创建一个 RequestType 的数组。这似乎是合理的,但它是,但你需要某种方式来表达。

At the same time it makes perfect sense to, for example, create an array of RequestType when we KNOW that all of them use the LegoModel. This seems reasonable, and it is, but you need some way to express that.

一种方法是创建一个类(或结构或枚举)将真实类型与抽象模型类型名称相关联:

One way to do that is to create a class (or struct, or enum) that associates a real type with the abstract Model type name:

class LegoRequestType: RequestType {
  typealias Model = LegoModel

  // Implement protocol requirements here
}

现在完全合理要声明一个 LegoRequestType 数组,因为如果我们想要 frobulate 所有这些,我们都知道我们必须通过 LegoModel 每次。

Now it's entirely reasonable to declare an array of LegoRequestType because if we wanted to frobulate all of them we know we would have to pass in a LegoModel each time.

与关联类型的这种细微差别使任何使用它们的协议变得特殊。 Swift标准库有这样的协议,最显着的是 Collection Sequence

This nuance with Associated Types makes any protocol that uses them special. The Swift Standard Library has Protocols like this most notably Collection or Sequence.

为了让您创建一个实现 Collection 协议或一系列实现序列协议的事物的数组,标准库采用了一种叫做< type-erasure来创建结构类型 AnyCollection< T> AnySequence< T> 。类型删除技术在Stack Overflow答案中解释起来相当复杂,但是如果您在网上搜索,会有很多关于它的文章。

To allow you to create an array of things that implement the Collection protocol or a set of things that implement the sequence protocol, the Standard Library employs a technique called "type-erasure" to create the struct types AnyCollection<T> or AnySequence<T>. The type-erasure technique is rather complex to explain in a Stack Overflow answer, but if you search the web there are lots of articles about it.

我可以推荐一个视频从YouTube上的亚历克斯加拉格尔关于协议与关联类型(PAT)

I can recommend a video from Alex Gallagher on Protocols With Associated Types (PATs) on YouTube.

这篇关于Protocol只能用作通用约束,因为它具有Self或associatedType的要求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆