【问题标题】:What is the difference between private and fileprivate in Swift 4Swift 4 中的私有和文件私有有什么区别
【发布时间】:2018-03-17 06:06:38
【问题描述】:

在 Swift 4 中,由于现在 private 在同一源代码文件中的扩展中也可见,它与 fileprivate 访问修饰符有何不同?

背景:在 Swift 3 中,类中的私有变量在同一文件的扩展中不可见。为此,必须使用fileprivate

【问题讨论】:

    标签: swift access-control access-modifiers swift4 access-levels


    【解决方案1】:

    文件私有
    文件私有访问将实体的使用限制在其自己的定义源文件中。当在整个文件中使用这些细节时,使用文件私有访问来隐藏特定功能的实现细节。
    语法: fileprivate <var type> <variable name>
    示例: fileprivate class SomeFilePrivateClass {}


    私人
    私有访问将实体的使用限制为封闭声明,以及该在同一文件中的声明的扩展。当这些细节仅在单个声明中使用时,使用私有访问来隐藏特定功能的实现细节。
    语法: private <var type> <variable name>
    示例: private class SomePrivateClass {}


    以下是有关所有访问级别的更多详细信息:Swift - Access Levels

    回答您的问题: (在 Swift 3 中,类中的私有变量在同一文件的扩展中不可见。为此,必须使用 fileprivate。)

    是的,在 Swift 4.0 中,Private 现在可以在扩展名中访问,但在同一个文件中。如果您在其他文件中声明/定义扩展名,则您的扩展名将无法访问您的私有变量


    看看这些图片:
    文件: ViewController.swift
    这里扩展和视图控制器都在同一个文件中,因此私有变量testPrivateAccessLevel可以在扩展中访问


    文件: TestFile.swift
    这里的扩展和视图控制器都在不同的文件中,因此私有变量testPrivateAccessLevel在扩展中是不可访问的。


    这里的类 ViewController2ViewController 的子类,两者都在同一个文件中。这里私有变量testPrivateAccessLevel在子类中不可访问,但fileprivate可在子类中访问。

    【讨论】:

    • 现在看来private和file private可以互换使用了。您能否提供一个可以使用 private 但不能使用 fileprivate 的示例,反之亦然。
    • 感谢您的示例。我明白你的意思。但我担心的是,如果在上面的例子中,我交换关键字 private 和 fileprivate,输出不会改变。
    • 不,如果您将扩展名移到另一个文件中,fileprivate 也将无法访问。
    • 我猜在这种情况下访问修饰符是相似的。在其他情况下,例如在子类中,它们必须不同。即使在同一个文件中,您也无法从子类访问私有变量。
    • 这很有帮助!
    【解决方案2】:

    适用于 swift 4.0 及其版本
    私有
    仅在类及其扩展名中私有访问(当扩展名在同一个 .swift 文件中时)。

    文件私有
    只能在类及其扩展名和子类中进行文件私有访问(当扩展名或子类在同一个 .swift 文件中时)。

    【讨论】:

      【解决方案3】:
      ///////////////ViewController1.swift file
              class ViewController1 {
                  private func testPrivate() {
                      print("testPrivate")
                  }
                  fileprivate func testFilePrivate() {
                      print("testFilePrivate")
                  }
                  func doesNothing1() {
                      testPrivate() //success
                      testFilePrivate() //success
                  }
              }
              extension ViewController1 {
                  func doesNothingInExtensionSameFile() {
                      testPrivate() //success
                      testFilePrivate() //success
                  }
              }
              class SomeOtherClassInSameFile {
                  let vc1 = ViewController1()
                  func doesNothing() {
                     vc1.testPrivate() //throws error
                     vc1.testFilePrivate() //success
                  } 
              }
      ////////////// ViewController2.swift file
              extension ViewController1 {
                  func doesNothingInExtensionDifferentFile() {
                      testPrivate() //throws error
                      testFilePrivate() //throws error
                  }
              }
      

      【讨论】:

        【解决方案4】:

        privatefileprivate 访问级别与 Swift4 更接近了。

        访问方式的区别如下:

        fileprivate 成员 - 仅且完全在该 .swift 文件中

        private 成员 - 如果两者都存在于同一个 .swift 文件中,则仅在该类和该类的扩展中

        因此只有 fileprivate 成员(不是 private)可以在

        中访问
        • 同一个 .swift 文件中的子类
        • 类的实例(在另一个类中初始化)在同一个 .swift 文件中。

        【讨论】:

          【解决方案5】:

          公开与公开:

          • Public 不允许一个类被另一个类继承 模块/目标,而 Open 可以。
          • 公共方法不允许在另一个子类中被覆盖 模块/目标,而 Open 可以。

          除了上面两个是一样的。

          私有与文件私有:

          • (在单个文件中)Private 不允许访问子类中的(功能和属性),而 FilePrivate 允许。
          • (外部文件)Private 和 FilePrivate 都无法访问。

          除了上面两个是一样的。

          【讨论】:

          • @Cristik 是的,文件私有适用于整个文件,但我正在比较私有和文件私有。 Private 不允许访问子类内部。比较时,我们不得不这样说。在文件中我们可以有类、扩展和子类,因此 private 可以允许在类本身和扩展中访问,但不允许在特定文件中访问子类。
          【解决方案6】:

          “Private”只能在类中访问,“FilePrivate”只能在 .swift 文件中访问。

          【讨论】:

          • (这篇文章似乎没有为问题提供quality answer。请编辑您的答案,或者将其作为对问题的评论发布。)
          【解决方案7】:

          Private:类和类扩展中的访问。 FilePrivate : 类、子类、扩展中的访问,

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-05-11
            • 2011-08-27
            • 2017-02-10
            • 1970-01-01
            • 2019-11-04
            • 2010-09-29
            相关资源
            最近更新 更多