这是SWIFT中的有效协议声明:
protocol Proto1: class {
func method1() -> Self
func method2() -> [Proto1]
}
但这不是:
protocol Proto2: class {
func method1(param: Self)
func method2() -> [Proto2]
}
错误消息为:
协议“proto2”只能用作泛型约束,因为它具有自身或关联的类型要求
因此,当使用self
作为函数的返回类型时,Swift并不认为这是所定义协议的约束,因此可以使用协议本身作为函数的返回类型。但是当使用self
作为函数的参数类型时,其行为是完全不同的。
我想知道为什么会有这样的差别?
因为将self
作为方法的参数类型是没有用的。假设您可以:
protocol P {
func f(_ x: Self)
}
class A: P {
func f(_ x: Self) {
// not relevant
}
}
class B: A { }
现在假设我有:
func g(x: A) {
// what can I do with x?
}
事实是,没有办法调用x.f
。因为我可以将b
的实例传递给x
,在这种情况下,x.f
将接受b
。x
可能是a
的任何子类的实例,在编译时我无法知道这些子类,因此我不知道可以传递给x.f
什么。
将其与用作返回类型的self
进行比较:
protocol P {
func f() -> Self
}
// Implementation:
class A: P {
func f() -> Self {
self
}
}
class B: A { }
func g(x: A) {
let foo: A = x.f()
}
在这里,我们知道我至少可以将x.f
的返回值赋给a
类型的变量。即使x
是b
的实例,这意味着f
返回一个b
,我们仍然可以将它赋给a
类型的变量。