swift - 不识别符合协议(protocol)的结构数组

标签 swift struct protocols

我正在尝试创建一个方法,该方法采用符合 Swift 协议(protocol)的结构数组。

对于最简单的示例,我定义了一个空协议(protocol)和一个方法,该方法采用符合该协议(protocol)的对象数组并只打印它们

protocol SomeProtocol {}

func methodTakingProtocol(objects: [SomeProtocol]) {
    // do something with the array of objects
    print(objects)
}

但是,当我尝试向该方法提供一个符合 SomeProtocol 的结构数组时,我收到错误

struct SomeStruct: SomeProtocol {}

let arrayOfStructs = [ SomeStruct(), SomeStruct() ]

methodTakingProtocol(arrayOfStructs)
// ^ "Cannot convert value of type '[SomeStruct]' to expected argument type '[SomeProtocol]'"

仔细研究了一下,我发现我可以通过显式调用 SomeStructSomeProtocol 的采用来解决这个问题

let arrayOfStructs: [SomeProtocol] = [ SomeStruct(), SomeStruct() ]

// This will work
methodTakingProtocol(arrayOfStructs)

谁能告诉我这是怎么回事?这是一个我应该提交雷达的错误,还是有一些关于为什么编译器不能将这个结构数组识别为符合它们被标记为采用的协议(protocol)的推理?

最佳答案

这实际上是按预期工作的。为了将数组传递给方法,您必须强制转换它或将其显式声明为协议(protocol):

protocol SomeProtocol {}

struct SomeStruct: SomeProtocol {}

// explicitly typed
let arrayOfStructs:[SomeProtocol] = [ SomeStruct(), SomeStruct() ]

func foo(bar:[SomeProtocol]) { }

foo(arrayOfStructs) // Works!

这是一篇关于此主题的优秀文章:Generic Protocols & Their Shortcomings

But that begs the question; Why can't we use generic protocols outside of generic constraints?

The short answer is: Swift wants to be type-safe. Couple that with the fact that it's an ahead-of-time compiled language, and you have a language that NEEDS to be able to infer a concrete type at anytime during compilation. I can't stress that enough. At compile time, every one of your types that aren't function/class constraints need to be concrete. Associated types within a protocol are abstract. Which means they aren't concrete. They're fake. And no one likes a fake.

编辑:它仍然是一篇很棒的文章,但在重新阅读后我意识到它并不完全适用于此,因为我们讨论的是“具体协议(protocol)”而不是“通用协议(protocol)”。

关于swift - 不识别符合协议(protocol)的结构数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36396603/

相关文章:

ios - 无法使用委托(delegate)协议(protocol)设置标签中的值

ios - swift 中的 X 轴图表标签

swift - 如何在 Swift 中将字符串转换为 NSUUID?

arrays - 列出一个类的所有元素并将它们存储在一个数组中以一次性设置外观属性

数组和单个项目通用支持的 Swift 通用问题

protocols - Zigbee 和 Zigbee PRO 有什么区别?

c - sigaction 用法和解释

c - 程序不运行(RUN FINISHED 分段故障核心转储)

c++ - C++ 中的命名冲突 : How to access a struct member called "class"

ios - 使用哪种网络协议(protocol)在服务器和多个客户端之间同步资源