Swift 支持重載操作符的特性马僻,讓我們可以自定義一些簡單的計算。
最經(jīng)典的例子就是兩個二維向量之間的計算了。
首先我們定義一個二維向量荡灾,并創(chuàng)建兩個向量
struct Vector2D {
var x = 0.0
var y = 0.0
}
let v1 = Vector2D(x: 2.0, y: 3.0)
let v2 = Vector2D(x: 1.0, y: 4.0)
相加兩個向量:
let v3 = Vector2D(x: v1.x + v2.x, y: v1.y + v2.y)
這樣一次的話,感覺還好瞬铸。但是遇到復雜的運算的話批幌,這樣寫感覺就太啰嗦了,這時候重載操作符是最好的選擇嗓节。
func +(left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
這樣荧缘,我們相加兩個向量就簡單的多了
let v3 = v1 + v2
print(v3) // 輸出 Vector2D(x: 3.0, y: 7.0)
向量的內積運算符API中是沒有定義的,所以我們自定義一個內積運算符拦宣。
這里是Swift 3的實現(xiàn)方式(感覺看起來比之前的版本可讀性好多了)截粗。
// 自定義操作符 別名類型
infix operator +*: InnerProductPrecedence
// 自定義操作符的運算優(yōu)先級
precedencegroup InnerProductPrecedence {
// 結合律:內積的結果是一個 Double,不再會和其他內積結合使用恢着,所以這里寫成 none
associativity: none
// 優(yōu)先級設置:高于普通運算桐愉。
// MultiplicationPrecedence(代表乘法和除法)
// AdditionPrecedence(代表加法和減法)
higherThan: MultiplicationPrecedence, AdditionPrecedence
}
接下來我們就可以寫具體的運算實現(xiàn)了
func +*(left: Vector2D, right: Vector2D) -> Double {
return left.x * right.x + left.y * right.y
}
let result = v1 +* v2 // 14
precedencegroup
定義了一個操作符優(yōu)先級別。操作符優(yōu)先級的定義和類型聲明有些相似掰派,一個操作符比需要屬于某個特定的優(yōu)先級从诲。Swift 標準庫中已經(jīng)定義了一些常用的運算優(yōu)先級組,比如加法優(yōu)先級 (AdditionPrecedence) 和乘法優(yōu)先級 (MultiplicationPrecedence) 等靡羡,你可以在這里找到完整的列表系洛。如果沒有適合你的運算符的優(yōu)先級組,你就需要像我們在例子中做得這樣略步,自己指定結合律方式和優(yōu)先級順序了描扯。
infix
表示要定義的是一個中位操作符,即前后都是輸入趟薄;其他的修飾還包括 prefix 和 postfix绽诚,不再贅述
associativity
定義了結合律,即如果多個同類的操作符順序出現(xiàn)的計算順序杭煎。比如常見的加法和減法都是 left恩够,就是說多個加法同時出現(xiàn)時按照從左往右的順序計算 (因為加法滿足交換律,所以這個順序無所謂羡铲,但是減法的話計算順序就很重要了)蜂桶。點乘的結果是一個 Double,不再會和其他點乘結合使用也切,所以這里寫成 none
higherThan
運算的優(yōu)先級扑媚,點積運算是優(yōu)先于乘法運算的腰湾。除了 higherThan,也支持使用 lowerThan 來指定優(yōu)先級低于某個其他組疆股。