重載運算符
在Swift中,類和結構體是可以提供現有運算符的自定義實現,也就是重載現有運算符。三元運算符(a?b:c)和默認的默認的賦值符(=)是不可重載的
Infix 運算符
單目運算符
下面舉個例子來學習下如何重載運算符。
struct Vector2D {
var x = 0.0, y = 0.0
}
這里,首先定義一個結構體Vector2D, 我們要重載 '+', 使得兩個同類型結構體相加的結果如下圖所示

entension Vector2D {
static func + (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
}
```swift
let vector = Vector2D(x: 3.0, y: 1.0)
let anotherVector = Vector2D(x: 2.0, y: 4.0)
let combinedVector = vector + anotherVector
// combinedVector is a Vector2D instance with values of (5.0, 5.0)
雙目運算符
// 這段代碼為Vector2D類型提供了比較運算符
extension Vector2D {
static func == (left: Vector2D, right: Vector2D) -> Bool {
return (left.x == right.x) && (left.y == right.y)
}
static func != (left: Vector2D, right: Vector2D) -> Bool {
return !(left == right)
}
}
```swift
let twoThree = Vector2D(x: 2.0, y: 3.0)
let anotherTwoThree = Vector2D(x: 2.0, y: 3.0)
if twoThree == anotherTwoThree {
print("These two vectors are equivalent.")
}
// Prints "These two vectors are equivalent."
Prefix 和 Postfix 運算符
同樣的,我們也可以對前綴運算符和后綴運算符進行重載。
// 這段代碼為Vector2D類型提供了單目減運算,并且是前綴,也就是取負操作。
extension Vector2D {
static prefix func - (vector: Vector2D) -> Vector2D {
return Vector2D(x: -vector.x, y: -vector.y)
}
}
```swift
let positive = Vector2D(x: 3.0, y: 4.0)
let negative = -positive
// negative is a Vector2D instance with values of (-3.0, -4.0)
let alsoPositive = -negative
// alsoPositive is a Vector2D instance with values of (3.0, 4.0)
值得注意的是,在對前綴運算符或者后綴運算符重載的時候,必須在func關鍵字后加上prefix或postfix關鍵字。
組合運算符
組合賦值是其他運算符和賦值運算符一起執行的運算。如+=把加運算和賦值運算組合成一個操作。實現一個組合賦值符號需要把運算符的左參數設置成inout
,因為這個參數會在運算符函數內直接修改它的值。
extension Vector2D {
static func += (left: inout Vector2D, right: Vector2D) {
left = left + right
}
}
``` swift
var original = Vector2D(x: 1.0, y: 2.0)
let vectorToAdd = Vector2D(x: 3.0, y: 4.0)
original += vectorToAdd
// original now has values of (4.0, 6.0)
自定義運算符
有時候我們需要定義自己的運算符來實現各自需求,在自定義運算符的時候分為兩步,聲明,實現。
一個新的運算符的聲明應該是全局域,并且使用operator
關鍵字聲明的,運算符可以使用關鍵字prefix
, infix
, postfix
,分別聲明為前綴,中綴,后綴運算符。
看個例子:
// 在全局域聲明一個新的運算符
prefix operator +++
> ```swift
// 實現運算符
extension Vector2D {
static prefix func +++ (vector: inout Vector2D) -> Vector2D {
vector += vector
return vector
}
}
var toBeDoubled = Vector2D(x: 1.0, y: 4.0)
let afterDoubling = +++toBeDoubled
// toBeDoubled now has values of (2.0, 8.0)
// afterDoubling also has values of (2.0, 8.0)
此外還可以定義運算符的結合性(associativity)和優先級(precedence),結合性(associativity)的值可取的值有left,right和none。左結合運算符跟其他優先級相同的左結合運算符寫在一起時,會跟左邊的操作數結合。同理,右結合運算符會跟右邊的操作數結合。而非結合運算符不能跟其他相同優先級的運算符寫在一起。
結合性(associativity)的值默認為none,優先級(precedence)默認為100。
> ```swift
infix operator +- { associativity left precedence 140 }
func +- (left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y - right.y)
}
let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 4.0)
let plusMinusVector = firstVector +- secondVector
// plusMinusVector 此時的值為 (4.0, -2.0)