Swift 常量

Swift 常量(let)全解析

“一旦确定,永不改变” —— 写出 安全、高效、清晰 的 Swift 代码!


一、什么是常量?

let 声明的值,在初始化后不可修改

let pi = 3.14159
let appName = "SwiftDemo"
let maxLoginAttempts = 3

// pi = 3.14            // 错误!编译不通过
关键字可变性推荐场景
let不可变所有确定不变的值
var可变仅在需要修改时使用

Apple 官方黄金法则能用 let 就绝不用 var


二、为什么优先用 let

1. 线程安全

let config = loadConfig()  // 多线程访问也安全

2. 编译器优化

let count = 100            // 编译器可内联、优化

3. 防止意外修改

let userID = generateID()
// userID = 999         // 编译错误,杜绝 Bug

4. 函数式编程友好

let result = numbers.map { $0 * 2 }.filter { $0 > 10 }

三、常量 vs 变量:对比表

特性let 常量var 变量
可修改
线程安全❌(需同步)
性能更快(编译器优化)稍慢
内存可被内联需存储
推荐度⭐⭐⭐⭐⭐⭐⭐

四、常量的“伪可变”—— 内容可变,引用不变

引用不变,内部状态可变

let numbers = [1, 2, 3]
// numbers = [4, 5, 6]     // 错误!不能重新赋值

// 但数组是引用类型,内容可变
var mutableNumbers = numbers
mutableNumbers.append(4)   // OK

正确做法:用 let + 不可变集合

let immutableArray = [1, 2, 3]
// immutableArray.append(4) // 错误!数组不可变

五、结构体中的常量

struct User {
    let id: Int
    var name: String          // 结构体是值类型
}

let user = User(id: 1, name: "张三")
// user.id = 2               // 错误!let 结构体整体不可变
// user.name = "李四"        // 错误!

关键点let 结构体 = 整个结构体不可变


六、常量在类中的妙用

class APIClient {
    let baseURL: URL
    let timeout: TimeInterval = 30

    init(baseURL: URL) {
        self.baseURL = baseURL      // 初始化时赋值
    }

    func fetch() { ... }
}

let client = APIClient(baseURL: URL(string: "https://api.com")!)
// client.baseURL = ...         // 错误!常量不可改

七、全局常量(推荐)

// Config.swift
let API_BASE_URL = URL(string: "https://api.example.com")!
let APP_VERSION = "1.0.0"
let MAX_FILE_SIZE = 10 * 1024 * 1024  // 10MB

// 命名规范:全大写 + 下划线
let MAX_LOGIN_ATTEMPTS = 3

八、延迟常量?不存在!

错误lazy let语法错误

// lazy let data = loadData()  // 编译错误!

正确做法:

需求方案
延迟初始化lazy var
常量 + 延迟static let + 单例
class DataManager {
    static let shared = DataManager()

    let heavyData: [Int] = {
        print("加载数据...")
        return Array(1...1_000_000)
    }()
}

九、计算常量(Computed Constant)

struct Circle {
    let radius: Double

    // 计算常量(只读)
    var area: Double {
        return .pi * radius * radius
    }

    // 错误!不能有 setter
    // var area: Double { get { ... } set { ... } }
}

let circle = Circle(radius: 5)
print(circle.area)  // 78.539...

十、常量在协议中的应用

protocol APIEndpoint {
    var path: String { get }
    var method: String { get }
}

struct LoginEndpoint: APIEndpoint {
    let path = "/login"        // 常量符合协议
    let method = "POST"
}

十一、常量解构(Destructuring)

// 元组常量
let (status, message) = (200, "OK")
print(status)  // 200

// 数组解构(Swift 5.8+)
let colors = ["红", "绿", "蓝"]
let [primary, secondary, _] = colors
print(primary)  // 红

十二、常量最佳实践

1. 配置项全部用 let

let API_TIMEOUT: TimeInterval = 30
let CACHE_SIZE = 50 * 1024 * 1024

2. 函数参数优先 let

func process(user: User) {
    let name = user.name.uppercased()  // 局部常量
    let age = user.age ?? 0
    // ...
}

3. 循环中用 let

for item in items {
    let processed = transform(item)  // 每次循环都是常量
    print(processed)
}

4. 避免全局 var

// 坏
var currentTheme = Theme.light

// 好
class ThemeManager {
    static let shared = ThemeManager()
    private(set) var current = Theme.light
}

十三、实战小项目:配置中心

// Config.swift
struct AppConfig {
    static let shared = AppConfig()

    let apiURL = URL(string: "https://api.production.com")!
    let debugMode = false
    let maxRetryCount = 3
    let supportedLanguages = ["zh-Hans", "en"]

    private init() {}  // 防止外部创建
}

// 使用
if AppConfig.shared.debugMode {
    print("调试模式")
}

十四、常见错误 & 避坑

错误正确做法
let array = [1,2,3]; array.append(4)var 或复制后修改
lazy let heavy = load()static let + 单例
全局 var 配置改为 static let
let 结构体却修改属性理解值类型语义

十五、速查表:let 使用场景

场景推荐写法
配置static let
视图尺寸let width = 100
计算结果let result = calc()
循环变量for item in items { let x = ... }
函数返回值let user = fetchUser()

十六、练习题(当场写!)

// 1. 定义一个不可变的圆周率常量
let PI = 3.141592653589793

// 2. 创建一个配置结构体,所有属性为常量
struct ServerConfig {
    // 你的代码
}

// 3. 写一个函数,参数和返回值都用 let
func formatName(first: String, last: String) -> String {
    // 你的代码
}

答案(展开查看)

点击查看答案

// 2.
struct ServerConfig {
    let host = "api.example.com"
    let port = 443
    let useHTTPS = true
    let timeout = 30.0
}

// 3.
func formatName(first: String, last: String) -> String {
    let fullName = "\(last) \(first)"
    return fullName.uppercased()
}

总结:常量使用黄金法则

法则说明
1. 默认用 let只有确定要改才用 var
2. 配置用 static let全局唯一
3. 结构体属性能 letlet保证不可变
4. 计算结果用 let提高可读性
5. 避免 lazy let语法错误

你已完全掌握 Swift 常量!


回复关键词继续学习

  • Swift 不可变集合
  • Swift 属性包装器(@State, @ObservedObject)
  • Swift 函数式编程
  • SwiftUI 状态管理

现在就全局搜索你的项目,把能改成 letvar 全改了!

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部