根据评论中引用的错误消息,以下内容失败。它已被归结为最低限度,因此下面的代码没有明显的实用价值。我只是试图处理真正奇怪的(在我看来)错误消息。我想将数组声明为[P]
而不是[S]
的原因是数组内容的通常运行时多态性。
protocol P {
func sp()
}
struct S: P {
func sp() {}
}
extension Array where Element: P {
func am() {}
}
func t() {
let goodA = [S]()
goodA.am() // No problem
let badA = [P]()
badA.am() // Error: '[P]' is not convertible to 'P'
}
答案 0 :(得分:1)
协议声明定义了新的独立类型。尽管它们的行为与类,枚举和结构不同,但是它们可以充当变量或属性的类型(前提是没有相关的类型约束,但要坚持)。例如
protocol MyProtocol {}
let myConst: MyProtocol // myConst has type `MyProtocol`
在具有泛型where子句的协议扩展中,有两种不同的方法来约束所讨论的泛型类型:使用:_
或==
。两者之间是有区别的。
使用:_
冒号指定泛型类型与指定的类型或协议匹配。它可以被解读为“继承自”或“符合”。例如,扩展名中指定的所有内容仅在关联类型符合Equatable
或从SomeClass
继承时才适用
protocol AnotherProtocol {
associatedtype MyType
}
class SomeClass {}
extension AnotherProtocol where MyType: SomeClass {}
extension AnotherProtocol where MyType: Equatable {}
使用==
通用where子句中的==
运算符指定通用类型完全等于指定的类型,而没有其他类型。下面的代码给出了编译时错误
class CustomType {}
class CustomTypeII: CustomType {}
class MyClass: AnotherProtocol { typealias MyType = CustomTypeII }
extension AnotherProtocol where MyType == CustomType {
func myFunc() {}
}
let instance = MyClass()
instance.myFunc() // Error: `CustomTypeII` is not the same type as `CustomType`
不能使用==
运算符 将泛型类型约束为具有关联类型的协议。编译器会抱怨该协议具有关联的类型要求。
protocol ThirdProtocol {}
extension ThirdProtocol where Self == AnotherProtocol {} // Error: `AnotherProtocol` has associated type requirements
从本质上讲,规范是模棱两可的:没有单一的AnotherProtocol
类型,就像没有单一的Array
类型一样。协议中的关联类型类似于通用类型的通用参数。在这里,需要使用冒号来指定通用类型“是某种” AnotherProtocol
类型(不透明类型是由于需要指定具有关联类型约束的协议的特定“类型”,因此超出了问题)。
您的扩展程序
Array
的扩展名仅适用于其元素为符合协议类型P
的某种类型的数组实例,不适用于其元素为P
的数组。不符合自己的协议类似于不继承自自己的类。
这是一个旧线程,但希望能有所帮助。