现在位置: 首页 > Swift 教程 > 正文

Swift 变量

变量用来保存会变化的值,Swift 用 var 声明变量。

和 C、Java 不同,Swift 的变量必须先初始化才能读取,编译器不允许使用没有赋值的变量。

本篇讲 var 的声明与修改、类型标注与类型推断、延迟初始化、命名规则和字符串插值;确定之后不再改变的值请用 let,写法见《Swift 常量》。


用 var 声明变量

var 声明一个可以重新赋值的变量,第一次赋值叫初始化,之后每次赋值都会覆盖旧值。

变量名写在 var 后面,等号右边是初始值。

实例

import Foundation

// var 声明变量,声明后可以重新赋值
var site = "www.runoob.com"
print(site)

site = "RUNOOB"
print(site)

// 变量的新值可以基于旧值计算
var visits = 100
visits = visits + 50
print("访问量:\(visits)")

运行结果:

www.runoob.com
RUNOOB
访问量:150

同一个变量可以反复赋值,但每次赋的值必须和它当前的类型一致,否则编译不通过。

如果一行里只写一个变量名而不做别的事,编译器会给出 variable is unused 的警告,提醒你多半忘了写赋值目标。


类型标注与类型推断

声明变量时可以直接写类型,也可以交给编译器推断,两种写法都合法。

大多数情况下,编译器能根据初始值推断出准确的类型,所以类型标注可以省略。

实例

// 类型推断:根据初始值推断为 Int
var count = 43

// 类型标注:显式写明类型
var site: String = "RUNOOB"
var price: Double = 9.9

print(count, site, price)

运行结果:

43 RUNOOB 9.9

类型标注的语法是「变量名冒号空格类型」,例如 var site: String,冒号不能写成等号。

什么时候必须显式标注?下面几种情况推断不出来,或者推断结果不符合预期。

场景写法原因
只有声明没有初始值var name: String没有值可推断
浮点需要单精度var ratio: Float = 0.5默认推断为 Double
整数需要指定位宽var small: Int8 = 10默认推断为 Int
空数组需要元素类型var list: [String] = []空字面量无法推断

Swift 的数值字面量还有一套默认推断规则:带小数点的字面量默认是 Double,整数字面量默认是 Int。

实例

// 空数组推断不出元素类型,必须标注
var names: [String] = []
names.append("Runoob")
print(names)

// 想要单精度浮点时必须标注,不标注会推断为 Double
var ratio: Float = 0.5
print(ratio)

运行结果:

["Runoob"]
0.5

一行里也可以声明多个变量,每个变量各自推断或标注类型,彼此的类型可以不同。

实例

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

// 同一行也可以声明不同类型的变量,各自推断
var count = 3, ratio = 0.5, name = "RUNOOB"
print(count, ratio, name)

运行结果:

6
3 0.5 RUNOOB

唯一的要求是每个变量都能确定类型:要么有初始值,要么写了类型标注。写成 var x = 1, y 会报 type annotation missing in pattern。


变量的延迟初始化

变量不一定要在声明的那一行就赋值,可以只声明类型,稍后再赋值。

这种写法叫延迟初始化,只要在读取之前完成赋值就行,编译器会跟踪每个变量是否已经初始化。

实例

// 先声明类型,之后再赋值
var site: String
site = "www.runoob.com"
print(site)

// 变量可以反复赋值,最后一次的值生效
var status = 0
status = 1
status = 2
print("status =", status)

运行结果:

www.runoob.com
status = 2

延迟初始化最常见的场景是:值要等某个条件成立后才能算出来,或者要等到能拿到依赖的数据。

注意:延迟初始化不是 lazy。这里是在使用之前完成一次赋值,而 lazy 是属性首次访问时才计算,属于属性的一种修饰,会在《Swift 属性》介绍。


变量命名规则

Swift 的标识符规则很宽松,但宽松不等于随便写。

变量名可以由字母、数字、下划线以及大部分 Unicode 字符组成,但不能以数字开头,也不能包含空格、连字符、数学符号。

实例

// 中文标识符
var 课程名称 = "Swift 教程"
// 希腊字母标识符
var π = 3.14159
print(课程名称, π)

// 推荐的小驼峰写法
var siteName = "RUNOOB"
var isLoading = true
print(siteName, isLoading)

运行结果:

Swift 教程 3.14159
RUNOOB true

虽然中文和希腊字母都能编译,但正式项目建议统一使用英文小驼峰,方便团队协作和全局搜索。

下面这些命名习惯值得遵守。

规则推荐不推荐
见名知义,不用无意义缩写maxRetryCountmrc、a1
布尔值用 is、has、can 开头isLoadingloading
不要用下划线开头siteName_siteName
不要用关键字classNameclass

如果确实要用关键字当名字,只能用反引号包裹,例如 var `class` = "Swift",但这不是好习惯。


字符串插值

字符串插值是把变量或表达式的值直接嵌进字符串里的语法,比手动拼接更清晰。

语法是在双引号内部写反斜杠加圆括号,括号里放变量或任意表达式。

实例

var name = "Runoob"
var site = "www.runoob.com"
var year = 2024

print("欢迎访问 \(site),\(name) 教程更新于 \(year) 年")

// 插值里可以放表达式
var a = 3, b = 4
print("\(a) + \(b) = \(a + b)")

运行结果:

欢迎访问 www.runoob.com,Runoob 教程更新于 2024 年
3 + 4 = 7

插值里的表达式不能包含未转义的双引号和反斜杠,如果要在插值里写字符串,需要嵌套转义或者改用拼接。

插值默认调用值的 description 属性,所以自定义类型也能插值,输出的是它的描述。

注意:插值符号是反斜杠加左圆括号 \(,结尾是右圆括号,不要漏写或者写成 {}。如果确实要输出一个反斜杠,写两个反斜杠 \\。


常见问题

下面是变量部分最常被问到的几个问题。

什么时候该用 var

只有值确实需要改变时才用 var,例如计数器、累加器、状态标志;其余情况优先用 let,完整的判断标准见《Swift 常量》。

类型推断错了怎么办

加上类型标注即可,例如 var ratio: Float = 0.5,不加标注时 0.5 会被推断为 Double。

能不能一行声明多个变量

可以,一行里的每个变量各自推断或标注类型,彼此类型可以不同,例如 var x = 1, y = 2.5;只要每个变量都有初始值或类型标注,就不会报错。