编译器无法将私有扩展中的方法识别为私有

Art*_*nko 5 swift

我有以下一段代码:

class C {
    private enum E {
        // ...
    }
}

private extension C {
    func f(e: E) {    // error: Method must be declared private because its parameter uses a private type
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我使用错误方法private,编译器错误就会消失。我想知道这是 Swift 中的错误还是我没有得到什么?

Ham*_*ish 4

在顶层,private相当于fileprivate\xe2\x80\x93 ,表示private只能在封闭范围(以及相同文件扩展名)内访问,并且在顶层,该文件该范围。

\n\n

所以你在这里所拥有的相当于:

\n\n
class C {\n    private enum E {\n        // ...\n    }\n}\n\nfileprivate extension C {\n    // error: Method must be declared private because its parameter uses a private type.\n    func f(e: E) { \n        // ...\n    }\n}
Run Code Online (Sandbox Code Playgroud)\n\n

(出于这个原因,为了清楚起见,我总是写fileprivate而不是private在顶层)

\n\n

这使得问题更容易理解 \xe2\x80\x93 扩展方法f是默认的fileprivate,因此可以在整个文件的范围内访问,但它的参数类型为E,只能在类的范围内访问C

\n\n

正如您所发现的,您可以标记fprivate

\n\n
class C {\n  private enum E {\n    // ...\n  }\n}\n\nfileprivate extension C {\n  private func f(e: E) {\n    // ...\n  }\n}
Run Code Online (Sandbox Code Playgroud)\n\n

或者标记Efileprivate

\n\n
class C {\n  fileprivate enum E {\n    // ...\n  }\n}\n\nfileprivate extension C {\n  func f(e: E) {\n    // ...\n  }\n}
Run Code Online (Sandbox Code Playgroud)\n\n

为了解决问题,使扩展方法f与其参数类型具有相同的可见性E

\n