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. 结构体属性能 let 就 let | 保证不可变 |
4. 计算结果用 let | 提高可读性 |
5. 避免 lazy let | 语法错误 |
你已完全掌握 Swift 常量!
回复关键词继续学习:
Swift 不可变集合Swift 属性包装器(@State, @ObservedObject)Swift 函数式编程SwiftUI 状态管理
现在就全局搜索你的项目,把能改成 let 的 var 全改了!