13

斯威夫特 3.0

我知道fileprivate访问级别修饰符将函数/属性的使用限制在声明它的源文件中,并且private限制在声明的词法范围内。但似乎这条规则不适用于扩展。EG 此代码有效:

class Foo {
}

fileprivate extension Foo {
    var aa: Int {
        return aaa + 10
    }
}

private extension Foo {
    var aaa: Int {
        return 20
    }
}

有人可以帮我弄清楚它们之间的区别吗?谢谢。

斯威夫特 4.0

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

fileprivate可以在同一个文件中访问。

4

2 回答 2

11

当我们谈论类型成员时,差异才会出现。private将限制对同一类型定义中的其他方法的访问,而位于同一文件fileprivate中的任何东西都可以访问事物。.swift

对于生活在顶层(在类型定义之外)的东西,private并且fileprivate 做完全相同的事情。所以当你写

fileprivate extension Foo 
{
    var aa: Int 
    {
        return aaa + 10
    }
}

private extension Foo 
{
    var aaa: Int 
    {
        return 20
    }
}

你真的写了

fileprivate extension Foo 
{
    var aa: Int 
    {
        return aaa + 10
    }
}

fileprivate extension Foo 
{
    var aaa: Int 
    {
        return 20
    }
}

最终,编译器将同一协议上的两个扩展解析为一个扩展。

fileprivate extension Foo 
{
    var aa: Int 
    {
        return aaa + 10
    }
    var aaa: Int 
    {
        return 20
    }
}

如果你认为有两个这样的关键字是愚蠢的,一些 Swift 架构师 同意你的看法。我相信一些样式指南建议您只使用publicandprivate访问修饰符(以及internal修饰符,但默认情况下是一个),因为一般来说,限制在每个文件的基础上,而不是每个模块或每个类型的基础并不是特别有用。

如果必须使用fileprivate修饰符,则切勿在private类型范围之外使用修饰符。它令人困惑(因为private在那种情况下“真的”意味着fileprivate)并使您的代码更难阅读。

于 2017-04-07T21:51:26.033 回答
4

在 Swift 4.0 中,privatefileprivate的范围得到了扩展。
Private 现在可以在同一个文件中访问,在实际类/扩展之外。如果您在其他文件中声明/定义您的扩展名,那么此时您的私有变量将无法访问 fileprivate 将起作用


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


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


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

于 2017-10-06T06:32:03.980 回答