Swift 中 let 与 var 的真正区别:不仅关乎“可变”与否

原文:Swift Basics: The Real Difference Between let and var Explained with Examples

很多初学 Swift 的同学会把 letvar 的区别简单记忆成"常量 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。"

这条规则背后的逻辑是:

  1. 不可变数据天然线程安全,减少副作用;
  2. 编译器可以做更多优化(如栈上分配、内联);
  3. 阅读代码的人无需担心值被中途篡改。
场景 推荐关键字
用户 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

  1. 默认用 let,除非编译器报错提示你需要可变性。
  2. API 模型全部用 let,除非后端明确会推送增量更新。
  3. UI 状态(如 @State 属性)用 var
  4. 多线程或并发场景,优先把数据设计成不可变,减少锁竞争。
  5. 如果想让对象内部也不可变,考虑:
    • 把 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()   // ❌

选择 letvar 不仅是语法风格问题,更是设计决策。

当你写下 let 的那一刻,就向未来的维护者传递了"这里不会被意外修改"的承诺。

相关推荐
Dream_Ji1 天前
Swift入门(二 - 基本运算符)
服务器·ssh·swift
HarderCoder2 天前
Swift 6.1 `withTaskGroup` & `withThrowingTaskGroup` 新语法导读
ios·swift
HarderCoder2 天前
Swift 并发:Actor、isolated、nonisolated 完全导读
ios·swift
用户092 天前
Swift Feature Flags:功能切换的应用价值
面试·swiftui·swift
HarderCoder2 天前
Swift 5.9 `consume` 操作符:一次说清楚“手动结束变量生命周期”
swift
YungFan2 天前
iOS26适配指南之UIScrollView
ios·swift
HarderCoder3 天前
SwiftUI Preferences 完全指南:从“向上传值”到 Swift 6 并发安全
swiftui·swift
东坡肘子3 天前
苹果正在为系统级支持 MCP 做准备 | 肘子的 Swift 周报 #0104
swiftui·swift·apple
Dream_Ji3 天前
Swift 入门(一 - 基础语法)
开发语言·ios·swift
HarderCoder3 天前
async let 也能调度同步函数?——Swift 并发隐藏小技巧详解
swiftui·swift