条件符合性:不支持将“ T”用作对“ T”的具体类型符合性

时间:2018-12-16 18:45:42

标签: swift

在尝试了解条件一致性时,我有一些非常基本的代码:

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),除了实际使用示例中的代码外,它们显示了所有内容。

任何帮助将不胜感激

2 个答案:

答案 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}}。