Swift: `private` 和 `internal` 之间的访问级别?
Swift: access level between `private` and `internal`?
在我的 Swift 代码中,我经常使用 private 修饰符来限制 helper classes 的可见性。例如,在一个文件中,我将有一个 GridController
和一个 GridControllerModel
.
应用程序的其余部分应该可以访问 GridController
(UI),但是模型 class 完全是内部的,不应被应用程序的其余部分访问申请。
我可以在 Swift 中通过制作 classes private
并将它们保存在同一个文件中来解决这个问题。但随着 classes 变大,这变得笨拙。我想做的是将每个 class 保存在一个单独的文件中(为了编程方便),但阻止访问模型 class 除了 GridController
之外的任何东西(出于信息隐藏目的)。
在 Swift 中有什么方法可以做到这一点吗?
不,没有将可见性限制为仅特定一组文件的访问修饰符。但你可能不需要那个。
存在什么:
private
: 将可见性限制在同一源文件内。
internal
: 将可见性限制在同一模块内。
如果您构建的软件对于一个源文件来说太大了,但两者都定义了一个面向外部的接口和应该对该接口的客户端隐藏的内部细节...那么您可能在适合构建框架的水平上工作。然后,您的框架可以定义 internal
仅供其使用并与它向客户端公开的 public
接口分开的功能。
正如其他人所说,在 Swift 中没有办法完全按照您的意愿行事。
一种替代方法是在另一个文件中使用扩展名将 GridControllerModel 添加为 GridController 的嵌套子类型。例如
//GridControllerModel.swift
extension GridController {
struct GridControllerModel {
let propertyOne:String
let propertyTwo:String
}
}
这允许您的 GridController class 在其自己的单独文件中声明如下内容:
var model = GridControllerModel()
但是,应用程序的其余部分仍然可以像这样访问 GridControllerModel 类型:
//SomeOtherClass.swift
var nested = GridController.GridControllerModel()
因此,通过使模型类型成为 GridController 的 子类型,您确实实现了一些分离,但这不是真正的访问控制。从好的方面来说,它不会出现在 GridController class 之外的代码完成中,如 "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 的任何扩展之外的所有 classes 不可见和不可访问。
因此,我建议您今天考虑这种嵌套子类型方法,因为当 Swift 3.0 今年晚些时候到来时,它可能只需在子类型声明前添加一个关键字即可支持您想要的功能.同时,您还可以获得一些您想要的分离。
在我的 Swift 代码中,我经常使用 private 修饰符来限制 helper classes 的可见性。例如,在一个文件中,我将有一个 GridController
和一个 GridControllerModel
.
应用程序的其余部分应该可以访问 GridController
(UI),但是模型 class 完全是内部的,不应被应用程序的其余部分访问申请。
我可以在 Swift 中通过制作 classes private
并将它们保存在同一个文件中来解决这个问题。但随着 classes 变大,这变得笨拙。我想做的是将每个 class 保存在一个单独的文件中(为了编程方便),但阻止访问模型 class 除了 GridController
之外的任何东西(出于信息隐藏目的)。
在 Swift 中有什么方法可以做到这一点吗?
不,没有将可见性限制为仅特定一组文件的访问修饰符。但你可能不需要那个。
存在什么:
private
: 将可见性限制在同一源文件内。internal
: 将可见性限制在同一模块内。
如果您构建的软件对于一个源文件来说太大了,但两者都定义了一个面向外部的接口和应该对该接口的客户端隐藏的内部细节...那么您可能在适合构建框架的水平上工作。然后,您的框架可以定义 internal
仅供其使用并与它向客户端公开的 public
接口分开的功能。
正如其他人所说,在 Swift 中没有办法完全按照您的意愿行事。
一种替代方法是在另一个文件中使用扩展名将 GridControllerModel 添加为 GridController 的嵌套子类型。例如
//GridControllerModel.swift
extension GridController {
struct GridControllerModel {
let propertyOne:String
let propertyTwo:String
}
}
这允许您的 GridController class 在其自己的单独文件中声明如下内容:
var model = GridControllerModel()
但是,应用程序的其余部分仍然可以像这样访问 GridControllerModel 类型:
//SomeOtherClass.swift
var nested = GridController.GridControllerModel()
因此,通过使模型类型成为 GridController 的 子类型,您确实实现了一些分离,但这不是真正的访问控制。从好的方面来说,它不会出现在 GridController class 之外的代码完成中,如 "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 的任何扩展之外的所有 classes 不可见和不可访问。
因此,我建议您今天考虑这种嵌套子类型方法,因为当 Swift 3.0 今年晚些时候到来时,它可能只需在子类型声明前添加一个关键字即可支持您想要的功能.同时,您还可以获得一些您想要的分离。