溢出運(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)