Swift 变量与常量

"变量"是程序里存放数据的容器。Swift 用两个关键字 letvar 来声明,看似简单,但背后藏着 Swift 关于"安全"和"意图清晰"的重要设计哲学。本章讲透它。

1. let 与 var:一字之差,天壤之别

Swift 声明变量只用两个关键字:

// let:常量,声明后不可改(类似 const)
let pi = 3.14159
let languageName = "Swift"
// pi = 3.14            // 编译错误:let 不能重新赋值

// var:变量,可以修改
var counter = 0
counter = counter + 1
counter += 1
print(counter)         // 2

这看起来和 C/Java 的 const / let 没区别,但 Swift 的特别之处在于:默认应该用 let,只有需要修改时才用 var。这是社区约定,Xcode 也会给"应该用 let 的 var"黄色警告。理由是——不可变代码更容易理解、更容易并发安全

2. 类型推断 vs 显式标注

Swift 是静态类型语言——每个变量都有确定的类型。但大多数时候你不用写类型,编译器会自动推断:

// 类型推断:不写类型,编译器自动判断
let age = 25               // 推断为 Int
let price = 9.99           // 推断为 Double(不是 Float!)
let name = "小明"          // 推断为 String
let isOpen = true          // 推断为 Bool

// 显式类型标注:在变量名后加冒号和类型
let score: Int = 88
let rate: Double = 0.5
let label: String = "VIP"
let isValid: Bool = false

// 推断不出来或想用更窄类型时,显式标注
let weight: Float = 65.5   // 否则会推断为 Double

几个新手容易踩坑的点:

3. 多变量与元组

Swift 支持一次声明多个变量,以及通过元组把多个值组合:

// 一次声明多个同类型变量
var x = 0, y = 0, z = 0
x += 1; y += 2; z += 3
print(x, y, z)             // 1 2 3

// 元组:把多个值打包成一个
let coordinate = (lat: 39.9, lng: 116.4)
print(coordinate.lat)      // 39.9

// 解构赋值
let (success, message) = (true, "OK")
print(success, message)    // true OK

// 只取一部分,用下划线忽略
let (code, _) = (404, "Not Found")
print(code)                // 404

元组是 Swift 的一个亮点——其他语言(如 Python)也有,但 Swift 的元组可以命名元素,用起来像一个小 struct。函数返回多个值时尤其方便。

4. 变量作用域

每个变量只在声明它的代码块内有效。出了这个块就访问不到了。内层同名变量会"遮蔽"(shadow)外层:

// 作用域:变量只在声明它的代码块里有效
let globalGreeting = "Hi"

func talk() {
    let localMsg = "Hello"   // 只在 talk 内有效
    print(globalGreeting)    // 外层的能访问
    print(localMsg)
}

talk()
// print(localMsg)           // 编译错误:出了作用域

// 内层同名变量会"遮蔽"外层
let level = "外层"
if true {
    let level = "内层"
    print(level)            // 内层
}
print(level)                // 外层

这条规则和绝大多数语言一致。Swift 多了一条:常量声明后必须在使用前初始化(可先声明后赋值,但不能"未赋值就用")。

5. 类型别名 typealias

typealias 可以给现有类型起一个更易读的名字,不创建新类型,只是别名(类似 C 的 typedef):

// typealias:给现有类型起个更可读的名字
typealias ID = String
typealias Coordinate = (lat: Double, lng: Double)

let userId: ID = "U123456"
let beijing: Coordinate = (lat: 39.9, lng: 116.4)
print(userId, beijing.lat)

// 常用于闭包类型,避免一长串泛型
typealias Callback = (Result<Data, Error>) -> Void

// Swift 标准库里的 typealias 例子
// Int 在 64 位平台就是 Int64
// Swift.String = String  重复定义无意义,但能提升可读性

实战中 typealias 经常用于:让闭包类型签名更短、领域概念命名(把 String 起名 UserId 让代码意图清晰)、平台兼容(Int 在 32/64 位平台大小不同,Swift 替你处理了)。

6. 为何默认 let?Swift 的设计哲学

大多数语言里 const 是"加戏",而 Swift 把"不可变"作为默认推荐。原因有三:

建议:每次想用 var 时,先问自己"它真的需要变吗?"——能 letlet

7. 常见陷阱

小结

这一章你学会了声明变量(var)和常量(let),知道 Swift 默认推荐 let;了解了类型推断、显式标注、元组解构、作用域、typealias。下一篇我们看 Swift 的数据类型——Int、Double、Bool、String 这些基础类型都有什么讲究。

← 上一篇 Swift 基础语法

下一篇 Swift 数据类型

✈️💬