【问题标题】:Array of structs conforming to protocol not recognized符合协议的结构数组无法识别
【发布时间】:2016-07-23 15:18:03
【问题描述】:

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

对于这个最简单的例子,我定义了一个空协议和一个方法,该方法接受一个符合该协议的对象数组并打印它们

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]'"

查了一下,我发现我可以通过明确指出SomeStruct 采用SomeProtocol 来解决这个问题

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

// This will work
methodTakingProtocol(arrayOfStructs)

谁能告诉我这里发生了什么?这是一个我应该提交雷达的错误,还是有一些理由解释为什么编译器不识别这个结构数组符合它们被标记为采用的协议?

【问题讨论】:

  • 我不认为这是一个错误。编译器看到SomeStruct 的实例,因此将数组的类型设置为[SomeStruct]。要更改类型,您需要明确您的意图。不过,您可能会提交功能雷达。

标签: swift struct protocols


【解决方案1】:

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

protocol SomeProtocol {}

struct SomeStruct: SomeProtocol {}

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

func foo(bar:[SomeProtocol]) { }

foo(arrayOfStructs) // Works!

这里有一篇关于这个主题的优秀文章:Generic Protocols & Their Shortcomings

但这引出了一个问题;为什么我们不能在外面使用通用协议 通用约束?

简短的回答是:Swift 希望是类型安全的。将其与 事实上它是一种提前编译的语言,而且你有一个 需要能够随时推断出具体类型的语言 在编译期间。我怎么强调都不过分。在编译时,每个 您的一种不是函数/类约束的类型必须是 具体的。协议中的关联类型是抽象的。意思是 它们不是具体的。他们是假的。没有人喜欢假货。

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

【讨论】:

  • 感谢您的链接!在那篇文章中肯定有很多有趣的信息,不过,正如你所说,我不确定这是否适用于这个问题。当我有机会查看其中是否有任何可能阐明情况的内容时,我将在 Apple 文档中进行一些挖掘。
猜你喜欢
  • 1970-01-01
  • 2016-02-02
  • 2021-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多