原文:Swift Basics: The Real Difference Between let and var Explained with Examples
很多初学 Swift 的同学会把 let
和 var
的区别简单记忆成"常量 vs 变量"。
但在实际工程中,这条规则只是起点。选择 let
还是 var
会直接影响代码的安全性、可读性,甚至运行时性能。
基础语义:可变与不可变
var
:可变变量。值在生命周期内可以被重新赋值或修改。let
:不可变绑定。一旦赋值,就不能再指向别的值。
swift
// var 可以改
var score = 10
score += 5 // ✅ 11
// let 不能改
let pi = 3.14
pi = 3.1415 // ❌ Cannot assign to value: 'pi' is a 'let' constant
何时用 let,何时用 var?
官方社区的最佳实践:"先写 let,必要时再改成 var。"
这条规则背后的逻辑是:
- 不可变数据天然线程安全,减少副作用;
- 编译器可以做更多优化(如栈上分配、内联);
- 阅读代码的人无需担心值被中途篡改。
场景 | 推荐关键字 |
---|---|
用户 ID、出生日期、API 返回的只读模型 | let |
计分器、计时器、用户输入框内容 | var |
SwiftUI 的 @State 包装属性 |
var (因为框架会重新赋值) |
示例:
swift
let identityNumber = "12345678900" // 一辈子不会变
var currentCity = "Erzurum" // 用户可能搬家
let 真的"绝对不变"吗?
答案是:取决于类型是值类型(Value Type)还是引用类型(Reference Type)。
引用类型(class)
swift
class Person {
var name: String
init(name: String) { self.name = name }
}
let person = Person(name: "Turabi")
person.name = "Muhammed" // ✅ 合法!
person
这个"变量名"不能指向别的对象;- 但对象内部的属性仍可以变动。
值类型(struct / enum)
swift
struct Book {
let title: String
}
let book = Book(title: "1984")
book.title = "The Art of War" // ❌ Cannot assign to property: 'book' is a 'let' constant
- 值类型实例被
let
修饰后,整个实例及其所有属性都不可变; - 如果想改属性,需要把实例声明为
var
,或者把属性声明为var
。
小结与实战 Checklist
- 默认用
let
,除非编译器报错提示你需要可变性。 - API 模型全部用
let
,除非后端明确会推送增量更新。 - UI 状态(如
@State
属性)用var
。 - 多线程或并发场景,优先把数据设计成不可变,减少锁竞争。
- 如果想让对象内部也不可变,考虑:
- 把 class 改成 struct;
- 或者把内部属性全部设为
let
。
附:完整示例
swift
// 1. 值类型:struct
struct Point {
let x: Int
let y: Int
}
let p = Point(x: 0, y: 0)
// p.x = 10 // ❌
// 2. 引用类型:class
class Counter {
var value: Int = 0
}
let counter = Counter()
counter.value += 1 // ✅
// counter = Counter() // ❌
选择
let
或var
不仅是语法风格问题,更是设计决策。
当你写下 let
的那一刻,就向未来的维护者传递了"这里不会被意外修改"的承诺。