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

Swift 字面量

字面量(literal)是直接写在源码里、一眼就能看出类型的值,例如 42、3.14、"Runoob" 和 true。

Swift 会根据字面量的写法和上下文推断类型,所以写代码时通常不需要额外标注。


什么是字面量

下面三行赋值,右侧都是字面量,左侧变量的类型由 Swift 自动推断出来。

实例

let aNumber = 3          // 推断为 Int
let aString = "Runoob"   // 推断为 String
let aBool = true         // 推断为 Bool

print(aNumber, aString, aBool)

以上程序执行结果为:

3 Runoob true

如果上下文无法推断,或者你想要更精确的类型,可以显式写类型标注,例如 let price: Double = 9.9。


整型字面量

整型字面量可以用十进制、二进制、八进制或十六进制书写,前三种写法最终得到的都是同一个 Int 值。

进制前缀示例十进制值
十进制无1717
二进制0b0b1000117
八进制0o0o2117
十六进制0x0x1117

数字中间可以插入下划线 _ 方便阅读,下划线会被完全忽略,不影响数值。

实例

let decimalInteger = 17           // 十进制
let binaryInteger = 0b10001       // 二进制
let octalInteger = 0o21           // 八进制
let hexadecimalInteger = 0x11     // 十六进制
print(decimalInteger, binaryInteger, octalInteger, hexadecimalInteger)

// 下划线只用于分隔,不参与计算
let oneMillion = 1_000_000
let cardNumber = 1234_5678_9012_3456
print(oneMillion, cardNumber)

以上程序执行结果为:

17 17 17 17
1000000 1234567890123456

注意:字面量本身没有固定的位宽,具体是 Int 还是 Int8 由上下文决定。上面的例子没有标注类型,Swift 统一推断为 Int。


浮点字面量

浮点字面量由整数部分、小数点、小数部分和指数部分组成,写法比整型多一些。

没有显式标注时,浮点字面量默认推断为 Double(64 位)。

写法示例值说明
普通十进制12.187512.1875最常见
十进制指数1.21875e112.1875乘以 10 的 1 次方
十六进制0xC.3p012.1875(12 + 3/16) × 2⁰
十六进制指数0x1p24.01 × 2²
下划线分隔1_000_000.000_000_11000000.0000001只为可读性

十六进制浮点数的指数部分用字母 p(而不是 e),表示乘以 2 的多少次方。

实例

let decimalDouble = 12.1875        // 普通十进制
let exponentDouble = 1.21875e1     // 1.21875 × 10¹
let hexDouble = 0x1p2              // 1 × 2² = 4.0
let hexDouble2 = 0xC.3p0           // (12 + 3/16) × 2⁰ = 12.1875
let readableDouble = 1_000_000.000_000_1
print(decimalDouble, exponentDouble, hexDouble, hexDouble2, readableDouble)

以上程序执行结果为:

12.1875 12.1875 4.0 12.1875 1000000.0000001

负数只需要在前面加一元减号,例如 -42.5,它等价于对字面量 42.5 取负。


字符串字面量

字符串字面量由一对双引号包起来,里面可以放普通字符、转义序列和插值表达式。

实例

let site = "www.runoob.com"
let greeting = "你好,\(site)"   // 反斜线加圆括号做字符串插值
print(greeting)

以上程序执行结果为:

你好,www.runoob.com

转义序列

Swift 支持的转义序列不多,只有下面这几个;写错了编译器会直接报错。

转义序列含义
\0空字符(null)
\\反斜线本身
\t水平制表符
\n换行
\r回车
\"双引号
\'单引号
\u{n}Unicode 标量,n 为 1 到 8 位十六进制数

实例

let stringL = "Hello\tWorld\n菜鸟教程:\"http://www.runoob.com\""
print(stringL)
print("反斜线:\\ 单引号:\'")

let han = "\u{4E2D}"
print("han = \(han),count = \(han.count)")

以上程序执行结果为:

Hello	World
菜鸟教程:"http://www.runoob.com"
反斜线:\ 单引号:'
han = 中,count = 1

注意:Swift 没有 C 语言里的 \b、\f、\v,也不支持八进制转义。写 "\b" 会得到 error: invalid escape sequence in literal。

多行字符串

用一对三引号 """ 可以写跨行的字符串,闭合三引号的缩进决定了每行被剥掉多少缩进。

实例

let text = """
    Runoob
    www.runoob.com
    "
""
print(text)
print("长度:\(text.count)")

// 多行字符串里可以直接写双引号,不需要转义
let quoted = """
他说:"
欢迎来到 Runoob"
"
""
print(quoted)

以上程序执行结果为:

Runoob
www.runoob.com
长度:21
他说:"欢迎来到 Runoob"

原始字符串

在三引号或双引号外面再加一个 #,就得到原始字符串:反斜线不再触发转义,\n 只是两个普通字符。

原始字符串里要做插值,需要在反斜线后再加一个 #,写成 \#(...)。

实例

// 反斜线不转义,\n 就是两个普通字符
let rawPath = #"目录 "C:\Users\Runoob" 里的 \n 不换行"#
print(rawPath)

// 原始字符串里插值要写成 \#(...)
let number = 17
let rawInterp = #"插值仍然可用:\#(number)"#
print(rawInterp)

以上程序执行结果为:

目录 "C:\Users\Runoob" 里的 \n 不换行
插值仍然可用:17

布尔字面量

布尔字面量只有两个:true 和 false,它们的类型是 Bool。

实例

let isRunoob = true
let isClosed = false
print(isRunoob, isClosed)
print("isRunoob 的类型是 \(type(of: isRunoob))")

以上程序执行结果为:

true false
isRunoob 的类型是 Bool

注意:nil 不是布尔字面量,它表示「没有值」,只能赋给可选类型。Swift 也没有「0、空字符串为假」这类隐式转换,条件位置必须放一个真正的 Bool,详见第 9 篇《Swift 条件语句》。


数组与字典字面量

数组字面量用方括号列出元素,字典字面量用「键: 值」的形式列出键值对。

实例

let sites: [String] = ["Runoob", "RUNOOB", "菜鸟教程"]
print(sites)
print("元素个数:\(sites.count)")

let info = ["name": "Runoob", "site": "www.runoob.com"]
print(info["name"]!, info["site"]!, info.count)

以上程序执行结果为:

["Runoob", "RUNOOB", "菜鸟教程"]
元素个数:3
Runoob www.runoob.com 2

注意:字典是无序的,遍历同一个字典两次,打印出的键值对顺序可能不同,所以上面用具体的键取值,而不是直接打印整个字典。


常见问题

下面几个问题是初学者写字面量时最常遇到的。

问题说明
浮点字面量为什么打印成 4.0它的类型是 Double,打印时会带上小数点
0b102 能编译吗不能,二进制只允许 0 和 1
字面量里的下划线会被算进数值吗不会,下划线只起分隔作用
"\b" 为什么报错Swift 没有这个转义序列,用 \u{8} 表示退格字符
字典字面量能保证顺序吗不能,字典本身无序