访问控制(Access Control)
- Swift提供了三种访问级别(Access Levels):
public(模块间访问级别,最高)
internal(模块内访问级别,中等,缺省)
private(文件内访问级别,最低)
注:这里模块是指作为独立单元来构建并发布,可以使用import关键字导入到其他模块的框架(Framework)或者应用程序(Application)。// 类的访问级别 public class SomePublicClass {} internal class SomeInternalClass {} private class SomePrivateClass {} // 常量,变量,函数的访问级别 public var somePublicVariable = 0 internal let someInternalConstant = 0 private func somePrivateFunction() {} // 缺省的访问级别 class SomeInternalClass {} // implicitly internal let someInternalConstant = 0 // implicitly internal
- 单一模块的应用通常使用缺省的internal访问级别就已经足够。
框架的 API应该使用public访问级别。
单元测试模块可以访问应用程序模块中所有 internal 访问级别的实体。
(需要@testable特性声明该实体并且使用testing enabled编译设置来编译product模块) - 访问控制原则:任何实体都不能用低于自己的访问级别的其他实体来定义。
- 类型的访问级别会影响其成员(属性,方法,构造器,下标)和嵌套类型的访问级别。
private类型的成员和嵌套类型的缺省访问级别为private。
public或者internal类型的成员和嵌套类型的缺省访问级别为internal。 - 元组的访问级别会被自动推导为元组成员中最低的访问级别。
- 函数的访问级别不得高于该函数的参数类型和返回类型的访问级别。
private func someFunction() -> (SomeInternalClass,SomePrivateClass) { // ... }
- 枚举中成员的访问级别继承自该枚举,不能单独指定。
枚举的原始值和关联值的访问级别不能低于枚举的访问级别。 - 子类的访问级别不得高于父类的访问级别。
但是子类成员的访问级别可以高于它所覆盖的父类成员的访问级别。public class A { private func someMethod() {} } internal class B: A { override internal func someMethod() {} }
- 常量,变量,属性不能拥有比自身类型更高的访问级别。
下标的访问级别不得高于该下标的索引类型和返回类型的访问级别。
常量,变量,属性,下标的Getters和Setters的访问级别继承自它们所属的常量,变量,属性,下标的访问级别。struct TrackedString { private(set) var numberOfEdits = 0 var value: String = "" { didSet { numberOfEdits += 1 } } } var stringToEdit = TrackedString() stringToEdit.value = "This string will be tracked." stringToEdit.value += " This edit will increment numberOfEdits." stringToEdit.value += " So will this one." print("The number of edits is \(stringToEdit.numberOfEdits)") // Prints "The number of edits is 3" public struct TrackedString { public private(set) var numberOfEdits = 0 public var value: String = "" { didSet { numberOfEdits += 1 } } public init() {} }
- 自定义构造器的访问级别可以低于或等于它所属类型的访问级别。
但是必要构造器的访问级别必须和所属类型的访问级别相同。
private类型的缺省构造器的访问级别为private。
public或者internal类型的缺省构造器的访问级别为internal。 - 如果结构体中的任一存储属性的访问级别为private,那么它缺省的成员逐一构造器访问级别就是private。
否则该成员逐一构造器的访问级别为internal。 - 协议中的所有需求(方法及属性)都具有和该协议相同的访问级别,不能单独指定。
与其它类型不同的是,public访问级别的协议中的所有需求也将是public访问级别。
继承了别的协议的协议所拥有的访问级别最高也只能与被继承协议的访问级别相同。
采纳了协议的类型的访问级别取决于类型本身的访问级别以及该类型所采纳的任何协议的访问级别中最低的一方。 - 扩展成员缺省具有和原始类型成员相同的访问级别。
采纳了协议的扩展的成员的访问级别与所采纳协议的访问级别相同,不能单独指定。 - 泛型类型或泛型函数的访问级别取决于以下访问级别中最低的一方。
该泛型类型或泛型函数本身的访问级别
任何施加于该泛型类型或泛型函数的类型参数之上的类型约束的访问级别 - 一个类型别名的访问级别不可高于它所指向类型的访问级别。