运算符是检查,改变,合并值的特殊符号或短语。例如,加号+将两个数相加(如let i = 1 + 2)。复杂些的运行算例如逻辑与运算符&&(如if enteredDoorCode && passedRetinaScan),又或让 i 值加1的便捷运算符自增运算符++i等。
Swift 支持大部分标准 C 语言的运算符,且改进许多特性来减少常规编码错误。如,赋值符(=)不返回值,以防止把想要判断相等运算符(==)的地方写成赋值符导致的错误。数值运算符(+,-,*,/,%等)会检测并不允许值溢出,以此来避免保存变量时由于变量大于或小于其类型所能承载的范围时导致的异常结果。当然允许你使用 Swift 的溢出运算符来实现溢出。详情参见溢出运算符。
区别于 C 语言,在 Swift 中你可以对浮点数进行取余运算(%),Swift 还提供了 C 语言没有的表达两数之间的值的区间运算符,(a..b和a...b),这方便我们表达一个区间内的数值。
本章节只描述了 Swift 中的基本运算符,高级运算符包含了高级运算符,及如何自定义运算符,及如何进行自定义类型的运算符重载。
术语
运算符有一元,二元和三元运算符。
一元运算符对单一操作对象操作(如-a)。一元运算符分前置符和后置运算符,前置运算符需紧排操作对象之前(如!b),后置运算符需紧跟操作对象之后(如i++)。
二元运算符操作两个操作对象(如2 + 3),是中置的,因为它们出现在两个操作对象之间。
三元运算符操作三个操作对象,和 C 语言一样,Swift 只有一个三元运算符,就是三元条件运算符(a ? b : c)。
受运算符影响的值叫操作数,在表达式1 + 2中,加号+是二元运算符,它的两个操作数是值1和2。
赋值运算符
赋值运算(a = b),表示用b的值来初始化或更新a的值:
let b = 10 var a = 5 a = b // a 现在等于 10
如果赋值的右边是一个多元组,它的元素可以马上被分解多个变量或变量:
let (x, y) = (1, 2) // 现在 x 等于 1, y 等于 2
与 C 语言和 Objective-C 不同,Swift 的赋值操作并不返回任何值。所以以下代码是错误的:
let (x, y) = (1, 2) // 现在 x 等于 1, y 等于 2
这个特性使得你无法把(==)错写成(=)了,由于if x = y是错误代码,Swift 从底层帮你避免了这些代码错误。
数值运算
Swift 让所有数值类型都支持了基本的四则运算:
加法(+)
减法(-)
乘法(*)
除法(/)
1 + 2 // 等于 3 5 - 3 // 等于 2 2 * 3 // 等于 6 10.0 / 2.5 // 等于 4.0
与 C 语言和 Objective-C 不同的是,Swift 默认不允许在数值运算中出现溢出情况。但你可以使用Swift 的溢出运算符来达到你有目的的溢出(如a &+ b)。详情参见溢出运算符。
加法运算符也用于String的拼接:
"hello, " +"world" // 等于"hello, world"
两个Character值或一个String和一个Character值,相加会生成一个新的String值:
l
et dog: Character = "d" let cow: Character = "c" let dogCow = dog + cow // dogCow 现在是 "dc"
详情参见字符,字符串的拼接。
求余运算
求余运算(a % b)是计算b的多少倍刚刚好可以容入a,返回多出来的那部分(余数)。
注意:
求余运算(%)在其他语言也叫取模运算。然而严格说来,我们看该运算符对负数的操作结果,"求余"比"取模"更合适些。
我们来谈谈取余是怎么回事,计算9 % 4,你先计算出4的多少倍会刚好可以容入9中:
2倍,非常好,那余数是1
在 Swift 中这么来表达:
9 % 4 // 等于 1
为了得到a % b的结果,%计算了以下等式,并输出余数作为结果:
a = (b × 倍数) + 余数
当倍数取最大值的时候,就会刚好可以容入a中。
把9和4代入等式中,我们得1:
9 = (4 × 2) + 1
同样的方法,我来们计算 -9 % 4:
-9 % 4 // 等于 -1
把-9和4代入等式,-2是取到的最大整数:
-9 = (4 × -2) + -1
余数是-1。
在对负数b求余时,b的符号会被忽略。这意味着 a % b 和 a % -b的结果是相同的。
浮点数求余计算
不同于 C 语言和 Objective-C,Swift 中是可以对浮点数进行求余的。
8 % 2.5 // 等于 0.5
这个例子中,8除于2.5等于3余0.5,所以结果是一个Double值0.5。
自增和自增运算
和 C 语言一样,Swift 也提供了方便对变量本身加1或减1的自增(++)和自减(--)的运算符。其操作对象可以是整形和浮点型。 ?
var i = 0 ++i // 现在 i = 1
每调用一次++i,i的值就会加1。实际上,++i是i = i + 1的简写,而--i是i = i - 1的简写。
++和--既是前置又是后置运算。++i,i++,--i和i--都是有效的写法。
我们需要注意的是这些运算符修改了i后有一个返回值。如果你只想修改i的值,那你就可以忽略这个返回值。但如果你想使用返回值,你就需要留意前置和后置操作的返回值是不同的。
当++前置的时候,先自増再返回。
当++后置的时候,先返回再自增。
例如:
var a = 0 let b = ++a // a 和 b 现在都是 1 let c = a++ // a 现在 2, 但 c 是 a 自增前的值 1
上述例子,let b = ++a先把a加1了再返回a的值。所以a和b都是新值1。
而let c = a++,是先返回了a的值,然后a才加1。所以c得到了a的旧值1,而a加1后变成2。
除非你需要使用i++的特性,不然推荐你使用++i和--i,因为先修改后返回这样的行为更符合我们的逻辑。
一元负号
数值的正负号可以使用前缀-(即一元负号)来切换:
let three = 3 let minusThree = -three // minusThree 等于 -3 let plusThree = -minusThree // plusThree 等于 3, 或 "负负3"
一元负号(-)写在操作数之前,中间没有空格。
一元正号
一元正号(+)不做任何改变地返回操作数的值。
let minusSix = -6 let alsoMinusSix = +minusSix // alsoMinusSix 等于 -6
虽然一元+做无用功,但当你在使用一元负号来表达负数时,你可以使用一元正号来表达正数,如此你的代码会具有对称美。
复合赋值(Compound Assignment Operators)
如同强大的 C 语言,Swift 也提供把其他运算符和赋值运算(=)组合的复合赋值运算符,加赋运算(+=)是其中一个例子:
var a = 1 a += 2 // a 现在是 3
表达式a += 2是a = a + 2的简写,一个加赋运算就把加法和赋值两件事完成了。
注意:
复合赋值运算没有返回值,let b = a += 2这类代码是错误。这不同于上面提到的自增和自减运算符。
在表达式章节里有复合运算符的完整列表。 ?
比较运算
所有标准 C 语言中的比较运算都可以在 Swift 中使用。
等于(a == b)
不等于(a!= b)
大于(a > b)
小于(a < b)
大于等于(a >= b)
小于等于(a <= b)
注意:
Swift 也提供恒等===和不恒等!==这两个比较符来判断两个对象是否引用同一个对象实例。更多细节在类与结构。
每个比较运算都返回了一个标识表达式是否成立的布尔值:
1 == 1 // true, 因为 1 等于 1 2 != 1 // true, 因为 2 不等于 1 2 > 1 // true, 因为 2 大于 1 1 < 2 // true, 因为 1 小于2 1 >= 1 // true, 因为 1 大于等于 1 2 <= 1 // false, 因为 2 并不小于等于 1
比较运算多用于条件语句,如if条件:
let name = "world" if name == "world" { println("hello, world") } else { println("I'm sorry \(name), but I don't recognize you") } // 输出 "hello,world", 因为 `name` 就是等于 "world"
关于if语句,请看控制流。