Swift:“私有”和“内部”之间的访问级别?

Posted

技术标签:

【中文标题】Swift:“私有”和“内部”之间的访问级别?【英文标题】:Swift: access level between `private` and `internal`? 【发布时间】:2016-07-09 18:44:44 【问题描述】:

在我的 Swift 代码中,我经常使用 private 修饰符来限制辅助类的可见性。例如,在一个文件中,我将有一个GridController 和一个GridControllerModel

GridController(UI)应该可供应用程序的其余部分访问,但模型类完全是内部的,不应被应用程序的其余部分访问。

我可以在 Swift 中通过创建两个类 private 并将它们保存在同一个文件中来解决这个问题。但是随着班级越来越大,这变得笨拙。我想做的是将每个类保存在一个单独的文件中(为了编程方便),但除了GridController(出于信息隐藏目的)之外,禁止访问模型类。

在 Swift 中有没有办法做到这一点?

【问题讨论】:

没有。正如您所注意到的,在 Swift 中执行此操作的正确方法是将它们放在同一个文件中。 【参考方案1】:

正如其他人所说,没有办法在 Swift 中完全按照您的意愿行事。

另一种方法是使用另一个文件中的扩展来将 GridControllerModel 添加为 GridController 的嵌套子类型。例如

//GridControllerModel.swift

extension GridController 
    struct GridControllerModel 
        let propertyOne:String
        let propertyTwo:String
    

这允许您的 GridController 类在其自己的单独文件中声明如下内容:

var model = GridControllerModel()

但是,应用程序的其余部分仍然可以像这样访问 GridControllerModel 类型:

//SomeOtherClass.swift

var nested = GridController.GridControllerModel()

因此,您确实可以通过使模型类型成为 GridController 的 子类型 来实现一些分离,但这并不是真正的访问控制。从好的方面来说,它不会在 GridController 类之外的代码完成中显示为“GridControllerModel”,您需要先键入“GridController”,然后键入“.”。查看子类型“GridController.GridControllerModel”

另外值得注意的是,目前正在审查额外的访问控制级别,并且可能会出现在 Swift 的下一版本 (3.0) 中:

https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md

假设此提案被接受并实施,您将能够像这样更新您声明的子类型:

//GridControllerModel.swift

local extension GridController 
    struct GridControllerModel 
        let propertyOne:String
        let propertyTwo:String
    

(注意上面的“local”关键字)。这将使 GridControllerModel 类型对除 GridController 和 GridController 的任何扩展之外的所有类不可见且不可访问。

所以,我建议你今天考虑这种嵌套子类型方法,因为当 Swift 3.0 在今年晚些时候到来时,它很可能通过在你的子类型声明前添加一个关键字来支持你想要的东西。同时,你也得到了一些你想要的分离。

【讨论】:

谢谢 - 这是一个很棒的建议!【参考方案2】:

不,没有访问修饰符将可见性限制为仅特定文件集。但你可能不需要那个。

存在什么:

private:将可见性限制在同一源文件中。 internal:将可见性限制在同一模块内。

如果您正在构建的软件对于一个源文件来说太大了,但两者都定义了一个面向外部的界面和应该对该界面的客户端隐藏的内部细节......那么您可能正在工作适合构建框架的级别。然后,您的框架可以定义 internal 仅供其使用的功能,并与它向客户端公开的 public 接口分开。

【讨论】:

以上是关于Swift:“私有”和“内部”之间的访问级别?的主要内容,如果未能解决你的问题,请参考以下文章

外部类与内部类的访问

Swift 中的友元类(访问内部类的私有成员)

为啥 Swift 的访问修饰符默认不是私有的?

[ Java学习基础 ] Java的封装性与访问控制

Swift 访问级别控制

如何在私有和受保护的访问修饰符之间进行选择以封装基类和子类之间的成员?