33

这是在 Playground 中完成的,只是为了简化。

class MyPrivateVar
{
    private var priv: String?
}

var myInstance = MyPrivateVar()

myInstance.priv = "Something"

没有编译器警告。事实上,自动完成显示priv没有问题。我的理解是,在课堂 {} 的边界之外,我不应该能够看到私有的任何东西,func也不应该看到var.

我错过了什么吗?

4

2 回答 2

48

Swift 中的访问修饰符的实现方式与其他语言不同。共有三个级别:

private: 只能在该特定文件中访问

internal:只能在模块(项目)内访问

public: 可从任何地方访问

除非另有标记,否则您编写的所有内容都是internal默认设置。

在 beta 4 中引入这些功能时,Swift 博客有一篇关于访问控制的文章,Apple文档也有一章

于 2014-09-28T18:14:36.900 回答
8

注意:此答案适用于 Swift 2


Swift 编程语言指出:

Swift 为代码中的实体提供了三种不同的访问级别。这些访问级别与定义实体的源文件相关,也与源文件所属的模块相关。

如果你不想private用 Swift 测试访问级别,下面的一步一步可能会对你有所帮助。

1/ 创建一个新的 Xcode 项目。

2/ 创建一个文件MyPrivateVar.swift,并在其中添加以下代码:

class MyPrivateVar {

    private var priv: String? = nil

}

3/ 创建第二个文件MySecondClass.swift,并在其中添加以下代码:

class MySecondClass {

    init() {
        var myPrivateVar = MyPrivateVar()
        myPrivateVar.priv = "some string"
    }

}

Xcode 会立即给你一个 Swift 编译器错误信息:

“MyPrivateVar”没有名为“priv”的成员

4/ 现在,从项目中删除之前的两个文件并创建一个文件TwoClassesInAFile.swift,其中包含以下代码:

class MyPrivateVar {

    private var priv : String? = nil

}

class MySecondClass {

    init() {
        var myPrivateVar = MyPrivateVar()
        myPrivateVar.priv = "some string"
    }

}

这一次,您将不会收到 Swift 编译器错误消息,并且您将能够访问MyPrivateVarpriv私有属性,MySecondClass因为privMySecondClass在同一个文件中(您的TwoClassesInAFile.swift文件)。

此外,访问级别也适用于全局变量。例如,如果以下代码是同一个ViewController.swift文件的一部分,Xcode 不会给出任何编译器错误:

import UIKit

private var globalPrivate : String? = nil

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        globalPrivate = "some string"
        println(globalPrivate)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

但是,如果您在ViewController.swiftglobalPrivate之外定义,Xcode 将生成错误消息:

使用未解析的标识符“globalPrivate”

于 2014-09-28T21:00:25.033 回答