为什么具有协议一致性的扩展不能具有特定的访问级别?

Pao*_*olo 15 protocols access-levels swift swift-extensions

假设我们有以下示例代码:

protocol MyProtocol {
    func someFunction()
}

public class MyClass {

}

public extension MyClass: MyProtocol {
    func someFunction() {
        print("hello")
    }
}
Run Code Online (Sandbox Code Playgroud)

编译上面的代码会出现以下错误:

错误:'public'修饰符不能与声明协议一致性的扩展一起使用

如果我将扩展名标记为,则会出现同样的情况private.它好像不能设置符合协议的扩展的访问级别,无论使用什么访问级别设置为中.甚至将协议声明设置为publicprivate不删除错误.

如果Swift符合协议,Swift以这种方式限制扩展访问级别的原因是什么?如果在类级别应用协议一致性,则不存在此类限制.

如果我服从编译器并删除private/ public指定,那么访问级别是someFunction()多少?

extension MyClass: MyProtocol {
    func someFunction() {
        print("hello")
    }
}
Run Code Online (Sandbox Code Playgroud)

我想在这种情况下,它将遵循原始的MyClass实现,public但我不确定.

这种行为是否存在,因为扩展中的协议一致性意味着整个类符合协议,因此在扩展中重新指定访问级别是多余的?

Lil*_*ard 19

这是因为除了协议本身的访问级别之外,不可能在任何访问级别上遵循协议.换句话说,如果您有public协议,则无法private符合协议.这部分是因为协议一致性是可以在运行时查询的东西(因此在你所在的模块之间不一致,或者在不同的文件/模块中实现两次),部分原因是因为如果一个模块只是很奇怪类型符合一个文件中的协议,并且在其他文件中使用时不符合该协议.

至于您的访问级别问题someFunction,它遵循与任何其他功能相同的规则.也就是说,它默认为internal,除非类型本身具有较低的访问级别.所以你的情况,如果MyClassMyProtocol是两个public,你可以期望得到一个编译错误告诉你someFunction()需要被标记public为好.但MyProtocol事实上internal,因为它实际上是省略任何访问修饰符的someFunction()默认设置internal.


Say*_*nuj 5

Private conformance might violate Liskov Substitution Principle

Quoting an abstract from apple devloper forum reply to a similar question:

"The biggest thing I've noted about private conformance, especially amonst classes that are meant to be subclassed further, is that you often end up with conflicting implementations."

例如,您有一个私有地遵守协议并实现其所有方法的类。后来出现了一个子类,并且想要做同样的事情,但只想实现所需的方法(因为未实现的可选方法可能会提供子类想要的一些默认行为)。但现在你有两个问题:

1) 期望实现此协议的对象现在可能在同一对象上有 2 个协议使用者。这导致两个对象都必须防范意外调用。或者没有,因为由于私有一致性,子类无法调用 super 来解决意外调用。

2)子类无法在不修改协议的情况下获得它想要的行为,因为超类的实现也无法在不影响其行为的情况下被删除。

来源:Apple 开发者论坛帖子链接