提问者:小点点

为什么使用Self作为返回类型不被认为是协议的约束?


这是SWIFT中的有效协议声明:

protocol Proto1: class {
    func method1() -> Self
    func method2() -> [Proto1]
}

但这不是:

protocol Proto2: class {
    func method1(param: Self)
    func method2() -> [Proto2]
}

错误消息为:

协议“proto2”只能用作泛型约束,因为它具有自身或关联的类型要求

因此,当使用self作为函数的返回类型时,Swift并不认为这是所定义协议的约束,因此可以使用协议本身作为函数的返回类型。但是当使用self作为函数的参数类型时,其行为是完全不同的。

我想知道为什么会有这样的差别?


共1个答案

匿名用户

因为将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将接受bx可能是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类型的变量。即使xb的实例,这意味着f返回一个b,我们仍然可以将它赋给a类型的变量。