在尝试了解条件一致性时,我有一些非常基本的代码:
protocol Animal {
var name: String { get }
}
protocol Social {
func speak()
}
class Cat: Animal, Social {
var name: String
init(name: String) {
self.name = name
}
func speak() {
print("Meow")
}
}
class Dog: Animal, Social {
var name: String
init(name: String) {
self.name = name
}
func speak() {
print("Ruff")
}
}
extension Array: Social where Element: Social {
func speak() {
forEach { $0.speak() }
}
}
let array: [Social] = [Dog(name: "Rocco"), Cat(name: "Gozer")]
array.speak()
尝试执行最后一行array.speak()
时,出现错误:
“不支持将“社交”用作符合协议“社交”的具体类型。”
我读取延伸Array
所在行的方式是这样的:
如果数组中的所有元素均符合Social
,则该数组符合协议Social
。它是否正确?以下工作正常:
array.forEach { social in
social.speak()
}
这使我相信,就声明/初始化数组而言,我做对了。
我看过许多关于条件一致性的文章,但是没有人给我关于如何声明数组(如果这是我的问题)以便使用它并遵守协议Social
的基础知识。 / p>
我目前正在阅读雷·温德利奇(Ray Wenderlich)的书《迅捷学徒》(Swift Apprentice),除了实际使用示例中的代码外,它们显示了所有内容。
任何帮助将不胜感激
答案 0 :(得分:3)
将扩展名更改为元素是,而不是元素符合
extension Array where Element == Social {
func speak() {
forEach { $0.speak() }
}
}
约束Array : Social
不相关。
答案 1 :(得分:1)
协议不符合自身。 Element
表示Social
必须是符合Social
的类型。 Social
不是符合Social
的类型。 (想象一下init()
是否包含Social()
要求。Social
将返回哪个类?这就是[Social]
不符合其自身的原因。)
在这种情况下,您可能希望[Dog]
和speak()
都获得Element == Social
,在这种情况下,您(不幸的是)不得不通过复制扩展名来说明这一点。用于Element: Social
,一次用于{{1}}。