swift重載或自定義操作符

重載運算符

在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關鍵字后加上prefixpostfix關鍵字。

組合運算符

組合賦值是其他運算符和賦值運算符一起執行的運算。如+=把加運算和賦值運算組合成一個操作。實現一個組合賦值符號需要把運算符的左參數設置成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)
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • SwiftDay011.MySwiftimport UIKitprintln("Hello Swift!")var...
    smile麗語閱讀 3,865評論 0 6
  • 一、為什么要重載運算符 我們都知道所謂的運算符平常的也就是 + - * / 之類的,比如我們隨便寫個 1 + 2 ...
    HenryCheng閱讀 2,768評論 1 15
  • 1、概述 除了一些基本的操作符,Swift提供了幾種能夠執行更加復雜值操縱的高級操作符。其中包括你所熟悉的C和OC...
    本人莫等閱讀 678評論 0 0
  • 139.優先級和關聯性 運算符優先級給一些運算符提供更高的優先級; 這些運算符首先起作用。 運算符關聯性確定相同優...
    無灃閱讀 429評論 0 2
  • 奶粉為什么產生抱團? 1) 所謂的“抱團”現象,奶粉在未開罐、未漏氣的情況下打開密封,看見有大小不一的奶粉團塊,只...
    喻莉閱讀 4,462評論 0 0