19

使用 Swift 4,我在同一个文件中定义了两个结构,其中一个是私有的,所以这个文件是唯一可以访问它的文件。此外,我依赖于结构的默认/综合初始化程序,即我没有明确定义一个:

private struct A {
  private let string: String
  ...
}

struct B {
  func foo() {
    let a = A(string: "bar")
    ...
  }
}

但是,这将无法编译并出现以下错误:

由于“私人”保护级别,“A”初始化程序不可访问

我不想A访问其他文件,所以我尝试通过制作它来解决它fileprivate(这应该相当于private在这种情况下),但是会发生相同的编译错误(并且它仍然抱怨保护级别是private)。

有没有办法保留这个结构fileprivate并仍然获得一个公开所有未初始化属性的合成初始化程序?IEA.init(string:)

4

4 回答 4

27

事实证明,“私人访问级别”投诉是关于initializer,而不是结构。初始化器的访问级别仅与最易访问的实例变量一样可访问。

如果我将string实例变量设为 以外private的任何值,错误就会消失:

private struct A {
  let string: String
  // synthesized initializer:
  // init(string: String)
}

因此,鉴于B现在可以读取A's string,它也可以访问A's 初始化程序。

如果A有另一个private属性,那么它的初始化器将再次变为private

private struct A {
  let string: String
  private let int: Int
  // synthesized initializer:
  // private init(string: String, int: Int)
  ...
}
于 2018-06-12T05:00:29.907 回答
2

您可以定义初始化程序。它将帮助您保持这种结构private。主要问题是private let string编译器自动添加具有私有访问级别的初始化程序private init(string: String)

对于修复,您必须定义自己的初始化程序

private struct A {
    private let string: String

    fileprivate init(string: String) {
        self.string = string
    }

    func foo() {}
}

struct B {
    func bar() {
        A(string: "baz").foo()
    }
}

或者您可以使用属性fileprivate的访问级别string。在这种情况下,您不需要初始化程序。

private struct A {
    fileprivate let string: String

    func foo() {}
}

struct B {
    func bar() {
        A(string: "baz").foo()
    }
}
于 2018-06-12T05:22:03.547 回答
0

这是解决使用 SwiftUI 结构时可能发生的错误的另一种方法。

鉴于此代码将产生相同的错误,因为变量未初始化或编译器不知道该变量是否保证具有值。

struct MyView: View {
    // Compiler: ¯\_(ツ)_/¯ 
    // initializer is inaccessible due to 'private' protection level
    private var rows: [Int]

    var body: some View {
        Text("Some text")
    }
}

因此,您可以将其设为可选、未包装或使用值进行初始化。

struct MyView: View {
    // Initialized
    private var rows = [Int]()

    var body: some View {
        Text("Some text")
    }
}

MyView()被实例化时,编译器不会抱怨。

struct MyView_Previews: PreviewProvider {
    static var previews: some View {
        MyView()
    }
}
于 2021-12-30T04:14:40.960 回答
-2

我用了

private let s: String = "Some value"

这个对我有用..

于 2020-04-24T12:10:50.503 回答