重載運(yùn)算符
在Swift中续捂,類(lèi)和結(jié)構(gòu)體是可以提供現(xiàn)有運(yùn)算符的自定義實(shí)現(xiàn),也就是重載現(xiàn)有運(yùn)算符宦搬。三元運(yùn)算符(a牙瓢?b:c)和默認(rèn)的默認(rèn)的賦值符(=)是不可重載的
Infix 運(yùn)算符
單目運(yùn)算符
下面舉個(gè)例子來(lái)學(xué)習(xí)下如何重載運(yùn)算符。
struct Vector2D {
var x = 0.0, y = 0.0
}
這里间校,首先定義一個(gè)結(jié)構(gòu)體Vector2D, 我們要重載 '+', 使得兩個(gè)同類(lèi)型結(jié)構(gòu)體相加的結(jié)果如下圖所示
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)
雙目運(yùn)算符
// 這段代碼為Vector2D類(lèi)型提供了比較運(yùn)算符
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 運(yùn)算符
同樣的矾克,我們也可以對(duì)前綴運(yùn)算符和后綴運(yùn)算符進(jìn)行重載。
// 這段代碼為Vector2D類(lèi)型提供了單目減運(yùn)算憔足,并且是前綴胁附,也就是取負(fù)操作差购。
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)
值得注意的是,在對(duì)前綴運(yùn)算符或者后綴運(yùn)算符重載的時(shí)候汉嗽,必須在func關(guān)鍵字后加上prefix或postfix關(guān)鍵字。
組合運(yùn)算符
組合賦值是其他運(yùn)算符和賦值運(yùn)算符一起執(zhí)行的運(yùn)算找蜜。如+=把加運(yùn)算和賦值運(yùn)算組合成一個(gè)操作饼暑。實(shí)現(xiàn)一個(gè)組合賦值符號(hào)需要把運(yùn)算符的左參數(shù)設(shè)置成inout
,因?yàn)檫@個(gè)參數(shù)會(huì)在運(yùn)算符函數(shù)內(nèi)直接修改它的值洗做。
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)
自定義運(yùn)算符
有時(shí)候我們需要定義自己的運(yùn)算符來(lái)實(shí)現(xiàn)各自需求弓叛,在自定義運(yùn)算符的時(shí)候分為兩步,聲明诚纸,實(shí)現(xiàn)撰筷。
一個(gè)新的運(yùn)算符的聲明應(yīng)該是全局域,并且使用operator
關(guān)鍵字聲明的畦徘,運(yùn)算符可以使用關(guān)鍵字prefix
, infix
, postfix
毕籽,分別聲明為前綴,中綴井辆,后綴運(yùn)算符关筒。
看個(gè)例子:
// 在全局域聲明一個(gè)新的運(yùn)算符
prefix operator +++
> ```swift
// 實(shí)現(xiàn)運(yùn)算符
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)
此外還可以定義運(yùn)算符的結(jié)合性(associativity)和優(yōu)先級(jí)(precedence),結(jié)合性(associativity)的值可取的值有l(wèi)eft杯缺,right和none蒸播。左結(jié)合運(yùn)算符跟其他優(yōu)先級(jí)相同的左結(jié)合運(yùn)算符寫(xiě)在一起時(shí),會(huì)跟左邊的操作數(shù)結(jié)合萍肆。同理袍榆,右結(jié)合運(yùn)算符會(huì)跟右邊的操作數(shù)結(jié)合。而非結(jié)合運(yùn)算符不能跟其他相同優(yōu)先級(jí)的運(yùn)算符寫(xiě)在一起塘揣。
結(jié)合性(associativity)的值默認(rèn)為none包雀,優(yōu)先級(jí)(precedence)默認(rèn)為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 此時(shí)的值為 (4.0, -2.0)