Swift文件Chapter 26 高階運算子
除了基本運算子,Swift還提供了一些高階運算子。
位運算子
Swift支援C語言中的全部位運算子。
- 按位取反:
~
- 按位與:
&
- 按位或:
|
- 按位異或:
^
按位左移、右移運算子
按位左移運算子(<<
) 和 按位右移運算子(>>
)可以對一個數的所有位進行指定位數的左移和右移。
對一個數進行按位左移或按位右移,相當於對這個數進行乘以2或除以2的運算。將一個整數左移一位,等價於將這個數乘以2,同樣地,將一個整數右移一位,等價於將這個數除以2。
對無符號整數進行移位的規則如下(邏輯移位):
- 已存在的位按指定的位數進行左移和右移。
- 任何因移動而超出整型儲存範圍的位都會被丟棄。
- 用 0 來填充移位後產生的空白位。
有符號整數的移位是對二進位制補碼進行移位,當對有符號整數進行按位右移運算時,遵循與無符號整數相同的規則,但是對於移位產生的空白位使用符號位進行填充,而不是用0。這個行為可以確保有符號整數的符號位不會因為右移運算而改變,這通常被稱為算術移位。
溢位運算子
Swift提供三個運算子,當發生溢位時不會報錯,而是會直接截斷。分別是溢位加法(&+
),溢位減法(&-
),溢位乘法(&*
)。
運算子函式
類和結構體可以為現有的運算子提供自定義的實現。這通常被稱為運算子過載。
下面的例子展示瞭如何讓自定義的結構體支援加法運算子(+)。算術加法運算子是一個二元運算子,因為它是對兩個值進行運算,同時它還可以稱為中綴運算子,因為它出現在兩個值中間。
struct Vector2D {
var x = 0.0, y = 0.0
}
extension Vector2D {
static func + (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
}
字首和字尾運算子
上個例子演示了一個二元中綴運算子的自定義實現。類與結構體也能提供標準一元運算子的實現。一元運算子只運算一個值。當運算子出現在值之前時,它就是字首的(例如 -a),而當它出現在值之後時,它就是字尾的(例如 b!)。
要實現字首或者字尾運算子,需要在宣告運算子函式的時候在func
prefix
或者postfix
修飾符。
複合賦值運算子
複合賦值運算子將賦值運算子(=)與其它運算子進行結合。例如,將加法與賦值結合成加法賦值運算子(+=)。在實現的時候,需要把運算子的左引數設定成 inout 型別,因為這個引數的值會在運算子函式內直接被修改。
extension Vector2D {
static func += (left: inout Vector2D, right: Vector2D) {
left = left + right
}
}
等價運算子
通常情況下,自定義的類和結構體沒有對等價運算子進行預設實現,等價運算子通常被稱為相等運算子(==)與不等運算子(!=)。
為了使用等價運算子對自定義的型別進行判等運算,需要為“相等”運算子提供自定義實現,實現的方法與其它中綴運算子一樣, 並且增加對標準庫Equatable協議的遵循。
多數簡單情況下,您可以使用 Swift 為您提供的等價運算子預設實現。Swift 為以下數種自定義型別提供等價運算子的預設實現:
- 只擁有儲存屬性,並且它們全都遵循 Equatable 協議的結構體;
- 只擁有關聯型別,並且它們全都遵循 Equatable 協議的列舉;
- 沒有關聯型別的列舉。
自定義運算子
新的運算子要使用 operator 關鍵字在全域性作用域內進行定義,同時還要指定 prefix、infix 或者 postfix 修飾符。
自定義中綴運算子的優先順序
每個自定義中綴運算子都屬於某個優先順序組。優先順序組指定了這個運算子相對於其他中綴運算子的優先順序和結合性。而沒有明確放入某個優先順序組的自定義中綴運算子將會被放到一個預設的優先順序組內,其優先順序高於三元運算子。