基本操作符
本章介绍Swift中的常见操作符,并介绍使用自定义操作符实现复杂运算。
<br />
术语
操作符包括一元、二元和三元运算符:
- 一元运算符包括前缀运算符(如-a)和后缀运算符(a!)。
- 二元运算符为中缀运算符。
- Swift只有一个三元运算符,即条件表达式(a ? b : c)。
<br />
赋值运算符
简单赋值运算:
let b = 10
var a = 5
a = b
元组赋值运算:
let (x, y) = (1, 2)
// x 等于 1, y 等于 2
与C和Objective-C不同的是,Swift的赋值运算符不返回该值,使得赋值运算符不可在if语句中作条件判断:
if x = y {
// 不合法,x = y不返回任何值
}
这个特性能避免在代码中将 == 写作 =
<br />
算术运算符
Swift支持加(+)、减(-)、乘(*)、除(/)四种数值运算。
与C和Object-C不同,Swift的算术运算符不允许值溢出,可选择溢出运算符(如&+b)对溢出选值。
加法运算符(+)可用在String中:
"hello, " + "world" // 等于 "hello, world"
求余运算符
一元减号运算符
let three = 3
let minusThree = -three
let plusThree = -minusThree
一元加法运算符
当和一元减法运算符一起使用时,可让代码更加对称。
复合赋值运算符
var a = 1
a += 2
// a 等于 3
注意
符合赋值运算符不返回任何值
<br />
比较运算符
标准C比较运算符
- a == b
- a != b
- a > b
- a < b
- a >= b
- a <= b
注意
== 和 !== 运算符用于判断两个对象是否引用同一个实例对象。
比较运算符常用于条件语句:
let name = "world"
if name == "world" {
print("hello, world")
} else {
print("I'm sorry \(name), but I don't recognize you")
}
// Prints "hello, world", because name is indeed equal to "world".
逻辑运算符可用于对元组类型的比较,从左到右依次比较:
(1, "zebra") < (2, "apple") // true because 1 is less than 2; "zebra" and "apple" are not compared
(3, "apple") < (3, "bird") // true because 3 is equal to 3, and "apple" is less than "bird"
(4, "dog") == (4, "dog") // true because 4 is equal to 4, and "dog" is equal to "dog"
只有当元组的每个元素能够应用该操作符时才能进行比较:
("blue", -1) < ("purple", 1) // OK, evaluates to true
("blue", false) < ("purple", true) // Error because < can't compare Boolean values
注意
Swift标准库只能对少于7个元素的元组使用比较运算符,否则必须自己实现比较运算符。
<br />
三元条件运算符
三元条件运算符(question ? answer1 : answer2)是以下代码的缩写:
if question {
answer1
} else {
answer2
}
三元条件运算符应谨慎使用,避免三元条件运算符的嵌套使用,这样会使代码可读性降低。
<br />
nil合并运算符
nil合并运算符(a ?? b)表明若可选类型a不为nil,则返回a的强制解包值,否则返回默认值b。
nil合并运算符是以下代码的缩写:
a != nil ? a! : b
nil合并运算符用于给可选类型设定默认值:
let defaultColorName = "red"
var userDefinedColorName: String? // 默认为 nil
var colorNameToUse = userDefinedColorName ?? defaultColorName
<br />
范围运算符
范围运算符是范围值的缩写形式。
闭合范围运算符
闭合范围运算符(a...b)表示包含a和b的从a到b的一系列整数值。
闭合范围运算符常用于迭代:
for index in 1...5 {
print("\(index)")
}
半开范围运算符
半开范围运算符(a..<b)表示包含a但不包含b的从a到b的一系列整数值。
半开范围运算符常用于集合类型的迭代:
let names = ["Anna", "Alex", "Brian", "Jack"]
let count = names.count
for i in 0..<count {
print("Person \(i + 1) is called \(names[i])")
}
单边范围运算符
单边范围忽略了双边范围的某一边,常用于数组元素遍历,如:
for name in names[2...] {
print(name)
}
for name in names[...2] {
print(name)
}
单边范围运算符也与半开范围形式,但是该单边必须在末尾,因为迭代起始不清楚,如:
for name in names[..<2] {
print(name)
}
单边范围也可用于判断是否包含特定值:
let range = ...5
range.contains(7) // false
range.contains(4) // true
range.contains(-1) // true
<br />
逻辑运算符
逻辑运算符与布尔值一起使用,有三种基本逻辑运算符:
- 逻辑非( !a )
- 逻辑与( a && b )
- 逻辑或( a || b )
逻辑非运算符
逻辑非运算符反转布尔值:
let allowedEntry = false
if !allowedEntry {
print("ACCESS DENIED")
}
仔细选择布尔常量和变量名可以帮助保持代码的可读性和简洁性,同时避免双重否定或混乱的逻辑语句。
逻辑与运算符
逻辑与运算符与C语言相同,也会出现短路现象。
let enteredDoorCode = true
let passedRetinaScan = false
if enteredDoorCode && passedRetinaScan {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
逻辑或运算符
逻辑或运算符也有短路现象。
let hasDoorKey = false
let knowsOverridePassword = true
if hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
组合逻辑运算符
使用组合逻辑运算符构建复杂的逻辑表达式:
if enteredDoorCode && passedRetinaScan || hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}
注意
逻辑与和逻辑与是左结合运算符,组合逻辑表达式会首先评估最左边的子表达式。
显式括号
在组合逻辑运算符中适当使用括号可提供代码的可读性并保持意图清晰。
if (enteredDoorCode && passedRetinaScan) || hasDoorKey || knowsOverridePassword {
print("Welcome!")
} else {
print("ACCESS DENIED")
}