在 Swift 中,访问控制(Access Control)是一种限制代码中实体(如类、结构体、属性和方法)访问范围的机制,它帮助开发者封装实现细节,提升代码的安全性和可维护性。Swift 提供 5 种访问级别,按权限从高到低依次为:open、public、internal、fileprivate 和 private。
1. Open(最高权限)
-
权限范围:允许在定义模块(Module)内外被访问、继承和重写。
-
适用场景:设计框架时,希望其他模块能继承或重写某个类或方法。
-
示例:
// 在框架的模块中定义 open class NetworkManager { open var timeout = 10.0 open func fetchData() { /* ... */ } } // 其他模块中使用 class CustomNetworkManager: NetworkManager { override func fetchData() { // 可以重写父类方法 } }
2. Public
-
权限范围:允许在定义模块内外被访问,但不能在其他模块中被继承或重写。
-
适用场景:暴露工具类或方法给其他模块使用,但限制其扩展。
-
示例:
// 在框架的模块中定义 public struct Logger { public static func log(_ message: String) { /* ... */ } } // 其他模块中使用 Logger.log("Hello") // ✅ 可以访问 // 但不能继承 Logger(因为不是 open)
3. Internal(默认级别)
-
权限范围:仅在定义模块内可访问,模块外不可见。
-
适用场景:应用程序内部代码,不需要暴露给其他模块。
-
示例:
// 在同一模块内的不同文件中 internal struct User { var name: String // 默认 internal } // 同一模块的其他文件 let user = User(name: "Alice") // ✅ 可访问
4. Fileprivate
-
权限范围:仅在当前源文件内可访问。
-
适用场景:同一文件中多个类型需要共享某些属性或方法。
-
示例:
// File: DataUtils.swift fileprivate struct Encryption { static func encrypt(_ data: String) -> String { /* ... */ } } public struct DataProcessor { func process(data: String) { let encrypted = Encryption.encrypt(data) // ✅ 同一文件内可访问 } } // 其他文件无法访问 Encryption
5. Private(最严格)
-
权限范围:仅在声明的作用域内(如类、结构体内部)可访问。
-
适用场景:隐藏类型内部的实现细节。
-
示例:
class BankAccount { private var balance: Double = 0.0 // 仅在类内部可访问 func deposit(_ amount: Double) { balance += amount // ✅ 可访问 } } let account = BankAccount() // account.balance ❌ 编译错误:不可访问
关键区别总结
| 访问级别 | 模块内访问 | 模块外访问 | 继承/重写权限 | 典型场景 |
|---|---|---|---|---|
open | ✅ | ✅ | ✅(允许) | 框架公开接口 |
public | ✅ | ✅ | ❌(不允许) | 工具类或方法 |
internal | ✅ | ❌ | - | 应用内部代码 |
fileprivate | 同一文件内 | ❌ | - | 文件内共享代码 |
private | 同一作用域内 | ❌ | - | 隐藏内部实现 |
使用建议
- 优先用
private:隐藏不需要暴露的实现细节。 - 框架设计用
open/public:明确区分可扩展的接口(open)和不可修改的工具(public)。 - 避免过度使用
fileprivate:仅在需要同一文件内共享时使用。