Swift 变量全解析(2025 版)
掌握 变量、常量、作用域、类型推断、延迟加载,让你写出 清晰、安全、高效 的 Swift 代码!
一、核心概念:var vs let
| 关键字 | 说明 | 是否可变 | 推荐场景 |
|---|---|---|---|
var | 变量(Variable) | 可修改 | 需要改变的值 |
let | 常量(Constant) | 不可修改 | 一旦确定就不变的值 |
var name = "小明" // 可变
let age = 18 // 不可变(推荐!)
name = "小红" // OK
// age = 20 // 错误!编译不通过
Apple 官方推荐:优先使用
let,只有确定要修改时才用var
二、类型推断(Type Inference)
Swift 是强类型语言,但支持自动推断类型:
let pi = 3.14 // Double
let count = 100 // Int
let flag = true // Bool
let greeting = "Hello" // String
显式声明类型(推荐在复杂场景)
let score: Int = 95
let price: Double = 9.99
let name: String = "张三"
三、变量命名规则
| 规则 | 示例 |
|---|---|
| 字母、数字、下划线 | userName, score_1 |
| 不能以数字开头 | var 1st = 1 错误 |
| 区分大小写 | age ≠ Age |
| 推荐:小驼峰 | userAge, totalScore |
| 常量:全大写(全局) | let MAX_LOGIN_ATTEMPTS = 3 |
let 🐶 = "旺财" // 支持 Emoji
let `let` = "关键字也可以用反引号" // 特殊情况
四、作用域(Scope)
let global = "全局变量"
func test() {
let local = "局部变量"
print(global) // OK
print(local) // OK
}
// print(local) // 错误!local 作用域仅在函数内
代码块作用域
if true {
let insideIf = "仅在 if 内"
print(insideIf)
}
// print(insideIf) // 错误!
五、延迟加载变量:lazy
只有第一次使用时才初始化,适合耗时操作
import Foundation
lazy var heavyData: [Int] = {
print("正在加载大量数据...")
return Array(1...1_000_000)
}()
print("开始")
print(heavyData[0]) // 第一次使用时才打印“正在加载...”
print("结束")
适用场景
- 大数组、复杂对象
- 视图控制器中的子视图
- 网络请求、文件读取
六、计算属性(Computed Property)
不是存储值,而是计算得出
struct Circle {
var radius: Double
var area: Double { // 计算属性
return .pi * radius * radius
}
var diameter: Double {
get { return radius * 2 }
set { radius = newValue / 2 }
}
}
var circle = Circle(radius: 5)
print(circle.area) // 78.54
circle.diameter = 20
print(circle.radius) // 10
七、属性观察器(Property Observer)
监控变量变化
class StepCounter {
var totalSteps: Int = 0 {
willSet(newValue) {
print("即将设置为 \(newValue)")
}
didSet {
if totalSteps > oldValue {
print("增加了 \(totalSteps - oldValue) 步")
}
}
}
}
let counter = StepCounter()
counter.totalSteps = 100 // 即将设置为 100
// 增加了 100 步
counter.totalSteps = 200 // 增加了 100 步
八、类型属性(static / class)
属于类型本身,不属于实例
struct Math {
static let pi = 3.14159
static func add(_ a: Int, _ b: Int) -> Int {
return a + b
}
}
print(Math.pi) // 3.14159
print(Math.add(3, 4)) // 7
九、变量的生命周期
| 类型 | 生命周期 |
|---|---|
| 全局变量 | 程序运行期间 |
| 局部变量 | 作用域结束时销毁 |
lazy 变量 | 第一次使用时创建,实例销毁时销毁 |
static | 程序运行期间 |
十、变量解构(Destructuring)
// 元组解构
let point = (x: 10, y: 20)
let (px, py) = point
print(px) // 10
// 数组解构(Swift 5.8+)
let colors = ["红", "绿", "蓝"]
let [first, second, _] = colors
print(first) // 红
// 字典遍历解构
let scores = ["张三": 95, "李四": 88]
for (name, score) in scores {
print("\(name): \(score)")
}
十一、变量安全最佳实践
1. 优先用 let
// 好
let userID = generateID()
var tempBuffer = Data()
// 坏
var userID = generateID() // 本来不会变
2. 延迟加载复杂对象
lazy var database = try! Database.connect()
3. 使用属性观察器监控关键变量
var isLoggedIn = false {
didSet { updateUI() }
}
4. 避免全局可变变量
// 坏:全局可变
var currentUser: User?
// 好:封装在单例或服务中
class UserService {
static let shared = UserService()
private(set) var currentUser: User?
}
十二、实战小练习
// 练习 1:银行账户
class BankAccount {
private(set) var balance: Double = 0 {
didSet {
print("余额:\(balance)")
}
}
func deposit(_ amount: Double) {
balance += amount
}
func withdraw(_ amount: Double) -> Bool {
guard amount <= balance else { return false }
balance -= amount
return true
}
}
let account = BankAccount()
account.deposit(1000)
account.withdraw(300)
// 练习 2:延迟加载配置
struct AppConfig {
static let shared = AppConfig()
lazy var apiURL: URL = {
print("加载配置...")
return URL(string: "https://api.example.com")!
}()
}
变量速查表
| 特性 | 语法 | 示例 |
|---|---|---|
| 常量 | let | let pi = 3.14 |
| 变量 | var | var count = 0 |
| 类型推断 | 自动 | let x = 10 |
| 显式类型 | : | var name: String |
| 延迟加载 | lazy | lazy var data = load() |
| 计算属性 | {} | var area: Double { ... } |
| 属性观察 | willSet/didSet | didSet { print("变了") } |
| 类型属性 | static | static let version = "1.0" |
总结:变量使用黄金法则
| 法则 | 说明 |
|---|---|
1. 能用 let 不用 var | 提高安全性 |
2. 复杂初始化用 lazy | 提升性能 |
| 3. 关键变量加观察器 | 及时响应变化 |
| 4. 全局变量要封装 | 避免副作用 |
| 5. 命名清晰有意义 | userAge > a |
你已完全掌握 Swift 变量!
回复关键词继续学习:
Swift 常量进阶Swift 属性包装器(@State, @Binding)Swift 内存管理SwiftUI 数据流
现在就打开 Playground,写一个带 didSet 的计步器!