【问题标题】:Pass an array of protocol conforming objects to function将一组符合协议的对象传递给函数
【发布时间】:2020-08-27 21:47:50
【问题描述】:

我想编写一个函数,它接受一个符合给定协议的对象数组。我编写了以下 Playground 代码:

protocol Request {}

struct RequestA: Request {}
struct RequestB: Request {}

func execute<T: Request>(requests: [T]) {}

let requests: [Request] = [RequestA(), RequestB()]

execute(requests: requests)

但是,在最后一行我收到此错误:“协议类型'Request' 的值不能符合'Request';只有结构/枚举/类类型可以符合协议”。

我相信这个错误正在发生,因为该函数需要一个符合协议的对象数组,而不是协议数组,但我不知道如何以另一种方式做到这一点。

有人可以帮忙解决这个问题吗?

提前致谢!

【问题讨论】:

  • 你只是不需要泛型类型T。将您的功能更改为此func execute(requests: [Request]) {}
  • 你真的需要在同一个集合中混合不同类型的对象吗?请注意,使用协议作为元素类型,只有协议所需的属性才能在该方法中访问。

标签: swift generics protocols


【解决方案1】:

正如其他人所说,您希望在这种情况下拥有func execute(requests: [Request]) {}

原因是func execute&lt;T: Request&gt;(requests: [T]) {} 作为一个泛型函数是说你想要一个符合Request 协议的具体已知类型T

[T] 更改为[Request] 让您拥有符合Request 的任何类型的数组,而不是符合的一种类型的数组。

【讨论】:

  • 谢谢,出于某种原因,我觉得我必须使用泛型。您能否举例说明在哪些情况下无法避免必须使用泛型?我可以想到可能有关联类型的协议。
  • 是的,如果有相关的类型或自我要求(也称为 PAT),那么您必须使用遗传学。举一个例子,如果你想使用 StringProtocol。它是一个 PAT,因此您需要按照您的方式对其进行约束,然后使实现采用 Array 或 String 或 Substring,但您不能在数组中将它们混合在一起。这有帮助吗?
【解决方案2】:
func execute(requests: [Request]) {}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    相关资源
    最近更新 更多