Swift 对计算属性的访问控制:为什么这有效?

Swift access control on computed properties: why does this work?

我似乎对 Swift 中的访问控制修饰符有一些误解。这是我在操场上的代码:

class Something {
    private (set) var name :String {
    get { return "" }
    set {}
    }
}
var thing = Something();
thing.name = "";

我的直觉和其他语言的经验告诉我,最后一行应该有编译错误。

然而,我正在学习的书指出,private 意味着被修改的成员只能从同一源文件访问。

我可以安全地假设这种情况在大多数项目中通常都是错误的吗,这只是因为我 运行 这段代码在操场上?

只能从同一源文件访问私有成员的说法是否完全准确?

The book I'm learning from however states that private means the member being modified is only accessible from the same source file.

并且您的示例是从同一个源文件访问它。有什么问题?

在Swift 3 中,private 变为fileprivate,其中允许从同一文件的任何位置访问。 Swift 3 中的 private 具有您期望的行为,其中仅允许在 class/struct/enum 本身内访问。

此规则对 Swift 2 的所有版本都有效。它对您的示例也有效,并且有效,因为您的 setter 代码在同一文件中(如果我理解您的示例正确)其中 setter 被调用。

允许使用顶级赋值表达式 thing.name = "";,因为它在 playground 中是 运行。在游乐场之外,这种特定的顶级分配在 大多数情况下 是非法的(有 例外!)。


关于 "top-level code" 的构成及其适用范围的额外解释;来自官方 Swift 博客 here:

However, top-level code is not allowed in most of your Swift source files. For clarity, any executable statement not written within a function body, within a class, or otherwise encapsulated is considered top-level. We have this rule because if top-level code were allowed in all your files, it would be hard to determine where to start the program.

...

You’ll notice that earlier we said top-level code isn’t allowed in most of your app’s source files. The exception is a special file named “main.swift”, which behaves much like a playground file, but is built with your app’s source code. The “main.swift” file can contain top-level code, and the order-dependent rules apply as well. In effect, the first line of code to run in “main.swift” is implicitly defined as the main entrypoint for the program. This allows the minimal Swift program to be a single line — as long as that line is in “main.swift”.