Swift學習(二十):高級運算符(溢出運算符,運算符重載,Equatable,Comparable,自定義運算符)

溢出運算符

  • Swift的算數運算符出現溢出時會拋出運行時錯誤
  • Swift有溢出運算符(&+、&-、&*),用來支持溢出運算
var umin = UInt8.min //0
var umax = UInt8.max //255

var min = Int8.min  //-128
var max = Int8.max //127

print(umax &+ 1) //0
print(umax &* 2) //254

UInt8.max + 1圖解:

 結果是0

UInt8.max * 2圖解:

結果是127


運算符重載

  • 類,結構體,枚舉可以爲現有的運算符提供自定義的實現,這個操作叫做運算符重載

preifx:前綴運算符

postfix:後綴運算符


Equatable

  • 要想得知2個實例是否等價,一般做法是遵守Equatable 協議,重載== 運算符 
  • 與此同時,等價於重載了 != 運算符

  • Swift爲以下類型提供默認的Equatable 實現 :
  1. 沒有關聯類型的枚舉
enum Answer {
    case wrong
    case right
}

var s1 = Answer.wrong
var s2 = Answer.right
print(s1 == s2)

有關聯類型會報錯:

    2.  只擁有遵守 Equatable 協議關聯類型的枚舉 

//Int, String都遵守Equatable協議
enum Answer : Equatable {
    case wrong(Int, String)
    case right
}

var s1 = Answer.wrong(10, "Jack")
var s2 = Answer.wrong(10, "Jack")
print(s1 == s2)

   //Cat()類型不遵守Equatable協議,會報錯

    

    3.   只擁有遵守 Equatable 協議存儲屬性的結構體

 

  • 引用類型比較存儲的地址值是否相等(是否引用着同一個對象),使用恆等運算符=== 、!==
class Person : Equatable {
    
    var age: Int
    init(age: Int) {
        self.age = age
    }
    static func == (lhs: Person, rhs: Person) -> Bool{
        return lhs.age == rhs.age
    }
}

var p1 = Person(age: 10)
var p2 = Person(age: 10)

print(p1 == p2) //true
print(p1 === p2) //false : ===比較的是存儲地址值,看是否是同一個對象,雖然p1和p2的age屬性值相同,但不是同一個對象,所以爲false

Comparable

  • 要想比較2個實例的大小,一般做法是:
  1. 遵守Comparable協議
  2. 重載相應的運算符


自定義運算符(Customer Operator)

  • 可以自定義新的運算符,在全局作用域使用operator進行聲明

associativity: left表示從左到右進行計算,right表示從右到左進行計算,none表示不能有兩個以上自定義的運算符在一條運算語句中同時使用

assignment:

class Person {
    var age = 0
    var point: Point = Point()
}
var p: Person? = Person()
p?.point +- Point(x: 10, y: 20) //這個運算符跟賦值運算符一樣當可選項p爲nil時,不會繼續進行運算,也就是Point(x: 10, y: 20)不會初始化

  •  Apple文檔參考:
  1. https://developer.apple.com/documentation/swift/swift_standard_library/operator_declarations
  2. https://docs.swift.org/swift- book/ReferenceManual/Declarations.html#ID380
prefix operator +++

prefix func +++ (_ i: inout Int) {
    i += 2
}

var age = 10
+++age
print(age) //12
infix operator +- : PlusMinusPrecedence

precedencegroup PlusMinusPrecedence {
    associativity: none
    higherThan: AdditionPrecedence
    lowerThan: MultiplicationPrecedence
    assignment: true
}

struct Point {
    var x: Int, y: Int
    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? = Person(point: Point(x: 11, y: 22))
var p1 = person?.point +- Point(x: 10, y: 20)
print(p1 ?? Point(x: 0, y: 0)) // Point(x: 21, y: 42)

var personOther: Person = Person(point: Point(x: 12, y: 23))
var p2 = personOther.point +- Point(x: 10, y: 20)
print(p2) // Point(x: 22, y: 43)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章