Swift-高級(jí)運(yùn)算符

【返回目錄】



溢出運(yùn)算符(Overflow Operator)

1.Swift的算數(shù)運(yùn)算符出現(xiàn)溢出時(shí)會(huì)拋出運(yùn)行時(shí)錯(cuò)誤

var int8: Int8 = Int8.max
print(int8 += 1)
報(bào)錯(cuò):Thread 1: Swift runtime failure: arithmetic overflow


2.Swift有溢出運(yùn)算符(&+、&-、&*)用來(lái)支持溢出運(yùn)算

var min = UInt8.min // 0
var max = UInt8.max // 255
var v1 = max &+ 1
print(v1) // 0

var v2 = min &- 1
print(v2) // 255

var v3 = max &* 2
print(v3) // 254  --> (255 * 2 - 255 - 1)




運(yùn)算符重載

類、結(jié)構(gòu)體、枚舉可以為現(xiàn)有的運(yùn)算符提供自定義的實(shí)現(xiàn),這通常被稱為運(yùn)算符重載。

struct Point {
    var x = 0, y = 0
    static func + (p1: Point, p2: Point) -> Point {
        Point(x: p1.x + p2.x, y: p1.y + p2.y)
    }
    static func - (p1: Point, p2: Point) -> Point {
        Point(x: p1.x - p2.x, y: p1.y - p2.y)
    }
    static prefix func - (point: Point) -> Point {
        Point(x: -point.x, y: -point.y)
    }
    static func += (p1: inout Point, p2: Point) {
        p1 = p1 + p2
    }
    static prefix func ++ (p: inout Point) -> Point {
        p += Point(x: 1, y: 1)
        return p
    }
    static postfix func ++ (p: inout Point) -> Point {
        let tmp = p
        p += Point(x: 1, y: 1)
        return tmp
    }
    static func == (p1: Point, p2: Point) -> Bool {
        (p1.x == p2.x) && (p1.y == p2.y)
    }
}
  • 相加
var p1 = Point(x: 100, y: 200)
var p2 = Point(x: 20, y: 20)
var p3 = Point(x: 30, y: 30)
print(p1 + p2)
print(p1 + p2 + p3)
  • 相減、取負(fù)數(shù)
print(p1 - p2)
print("取負(fù)數(shù):\(-p1)")
  • +=
p1 += p2
print(p1)
  • ++
var p1 = Point(x: 100, y: 200)
var p2 = ++p1
print(p2)

print(p1++)




Equatable

1.要想得知2個(gè)實(shí)例是否等價(jià),一般做法是遵守Equatable協(xié)議,重載==運(yùn)算符,與此同時(shí)等價(jià)于重載了 !=運(yùn)算符。

  • 示例1
class Person : Equatable {
    var age: Int
    init(age: Int) {
        self.age = age
    }
    static func == (lhs: Person, rhs: Person) -> Bool {
        lhs.age == rhs.age
    }
}
var p1 = Person(age: 10)
var p2 = Person(age: 20)
print(p1 == p2)
print(p1 != p2)


2.Swift為以下類型提供默認(rèn)的Equatable實(shí)現(xiàn)

  • 沒(méi)有關(guān)聯(lián)類型的枚舉
enum Answer {
    case wrong
    case right
}
var a1 = Answer.wrong
var a2 = Answer.right
print(a1 == a2) // false


  • 只擁有遵守Equatable協(xié)議的關(guān)聯(lián)類型的枚舉
enum Answer: Equatable {
    case wrong(Int)
    case right
}
var a1 = Answer.wrong(10)
var a2 = Answer.wrong(10)
print(a1 == a2) // true


  • 只擁有遵守Equatable協(xié)議存儲(chǔ)屬性的結(jié)構(gòu)體
struct Point:Equatable {
    var x: Int
    var y: Int
}
var p1 = Point(x: 10, y: 20)
var p2 = Point(x: 10, y: 20)
print(p1 == p2)


3.引用類型比較存儲(chǔ)的地址值是否相等(是否引用著同一個(gè)對(duì)象),使用恒等運(yùn)算符===!==

var p1 = Person(age: 10)
var p2 = p1
print(p1 == p2) // true
print(p1 === p2) // true




Comparable

  • 要想比較兩個(gè)實(shí)例的大小,一般的做法是:
    • 遵守Comparable協(xié)議
    • 重載相應(yīng)的運(yùn)算符
struct Student : Comparable {
    var age: Int
    var score: Int
    init(age: Int, score: Int) {
        self.age = age
        self.score = score
    }
    static func < (lhs: Student, rhs: Student) -> Bool {
        (lhs.score < rhs.score) || (lhs.score == rhs.score && lhs.age > rhs.age)
    }
    //返回true為lhs大,false為rhs小
    static func > (lhs: Self, rhs: Self) -> Bool {
        (lhs.score > rhs.score) || (lhs.score == rhs.score && lhs.age < rhs.age)
    }
    static func <= (lhs: Student, rhs: Student) -> Bool {
        !(lhs > rhs)
    }
    static func >= (lhs: Self, rhs: Self) -> Bool {
        !(lhs < rhs)
    }
}

var lhs = Student(age: 10, score: 10)
var rhs = Student(age: 20, score: 20)
var stu3 = Student(age: 30, score: 40)

print(lhs < rhs) //true
print(stu3 > rhs) //true
print(lhs <= rhs) //true
print(stu3 >= rhs) //true




自定義運(yùn)算符(Custom Operator)

Apple文檔參考:
【蘋果開(kāi)發(fā)者文檔】
【Swift 社區(qū)】


1.可自定義新的運(yùn)算符:在全局作用域使用Operator進(jìn)行聲明

prefix operator 前綴運(yùn)算符
postfix operator 后綴運(yùn)算符
infix operator 中綴運(yùn)算符 : 優(yōu)先級(jí)組
precedencegroup 優(yōu)先級(jí)組 {
    associativity: 結(jié)合性(left、right、none)
    higherThan: 比誰(shuí)的優(yōu)先級(jí)高
    lowerThan: 比誰(shuí)的優(yōu)先級(jí)低
    assignment: true 代表在可選鏈操作中擁有跟賦值運(yùn)算符一樣的優(yōu)先級(jí)
}
prefix operator +++
infix operator +- : PlusMinesPrecedence
precedencegroup PlusMinesPrecedence {
    associativity: none // none沒(méi)有結(jié)合性
    higherThan: AdditionPrecedence // 加號(hào)優(yōu)先級(jí)組
    lowerThan: MultiplicationPrecedence // 乘法優(yōu)先級(jí)組
    assignment: true
}


例如:自定義前綴運(yùn)算符

prefix operator +++
prefix func +++ (_ i: inout Int) {
    i += 2
}
var age = 10
+++age


自定義運(yùn)算符

struct Point {
    var x: Int
    var y: Int
    static prefix func +++ (point: inout Point) -> Point {
        point = Point(x: point.x + point.x, y: point.y + point.y)
        return point
    }
    static func +- (left: Point, right: Point) -> Point {
        return Point(x: left.x + right.x, y: left.y - right.y)
    }
    static func +- (left: Point?, right: Point) -> Point {
        print(" +- ")
        return Point(x: left?.x ?? 0 + right.x, y: left?.y ?? 0 - right.y)
    }
}

struct Person {
    var point: Point
}
var person: Person? = nil //Person(point: Point(x: 10, y: 20))
var point = person?.point +- Point(x: 11, y: 22)
print(point)






【上一篇】:范型
【下一篇】:擴(kuò)展




最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容