Swift访问控制

179 阅读2分钟

在 Swift 中,访问控制(Access Control)是一种限制代码中实体(如类、结构体、属性和方法)访问范围的机制,它帮助开发者封装实现细节,提升代码的安全性和可维护性。Swift 提供 5 种访问级别,按权限从高到低依次为:openpublicinternalfileprivate 和 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同一作用域内-隐藏内部实现

使用建议

  1. 优先用 private:隐藏不需要暴露的实现细节。
  2. 框架设计用 open/public:明确区分可扩展的接口(open)和不可修改的工具(public)。
  3. 避免过度使用 fileprivate:仅在需要同一文件内共享时使用。