Swift:运算符重载专题

1. 普通运算符和比较运算符

import Foundation

struct Vector3 {
    var x: Double
    var y: Double
    var z: Double
}

var va = Vector3(x: 1, y: 2, z: 3)
var vb = Vector3(x: 4, y: 5, z: 6)

func + (left: Vector3, right: Vector3) -> Vector3 { // 这个left和right可以随便起名字
    return Vector3(x: left.x + right.x, y: left.y + right.y, z: right.z + right.z)
}

va + vb

func * (left: Vector3, right: Vector3) -> Double {
    return left.x * right.x + left.y * right.y + left.z * right.z
}

va * vb

func * (left: Vector3, num: Double) -> Vector3 {
    return Vector3(x: left.x * num, y: left.y * num, z: left.z * num)
}

va * (-0.1)

func * (num: Double, right: Vector3) -> Vector3 {
    return right * num
}

5.78 * vb

// 注意 += 不需要有返回值
func += (left: inout Vector3, right: Vector3){
    left = left + right // 前面定义过
}

va += vb

// 单目运算符 -
// prefix表示的是 - 在左边,对应的关键字是postfix
prefix func - (vector: Vector3) ->Vector3 {
    return Vector3(x: -vector.x, y: -vector.y, z: -vector.z)
}

-va

// 比较运算符

func == (left: Vector3, right: Vector3) -> Bool {
    return left.x == right.x && left.y == right.y && left.z == right.z
}

va == vb

func != (left: Vector3, right: Vector3) -> Bool {
    return !(left == right)
}

va != vb

func < (left: Vector3, right: Vector3) -> Bool {
    return left.x < right.x && left.y < right.y && left.z < right.z
}
va < vb

func > (left: Vector3, right: Vector3) -> Bool {
    return left.x > right.x && left.y > right.y && left.z > right.z
}

va > vb

// 拿sort函数举个例子
let v1 = Vector3(x: 3, y: 4, z: 5)
let v2 = Vector3(x: 5, y: 12, z: 13)
let v3 = Vector3(x: -1, y: -2, z: -3)

var arr = [v1, v2, v3]
arr.sort(by: {v1, v2 -> Bool in
    let len1 = sqrt(pow(v1.x, 2) + pow(v1.y, 2) + pow(v1.z, 2))
    let len2 = sqrt(pow(v2.x, 2) + pow(v2.y, 2) + pow(v2.z, 2))
    return len1 < len2
})
arr

2. 自定义单目运算符和双目运算符

Ps:如果没有定义结合性和优先级,则func前面的prefix和postfix不能省

// 自定义运算符
// 单目
// 首先要先声明一下自己定义的+++
va = Vector3(x: 1, y: 2, z: 3)
prefix operator +++
prefix func +++ (vector: inout Vector3) -> Vector3 { // prefix不能省
    vector.x += 1
    vector.y += 1
    vector.z += 1
    return vector
}
+++va // 2, 3 ,4
va // 2, 3, 4


postfix operator +++
postfix func +++ (vector: inout Vector3) -> Vector3 { // postfix不能省
    let tmp = vector
    vector.x += 1
    vector.y += 1
    vector.z += 1
    return tmp
}
va+++ // 2, 3, 4
va // 3, 4, 5

// 双目
// 求两个向量之间的夹角
// infix表示这个自定义的运算符是双目运算符
infix operator ^
func ^ (left: Vector3, right: Vector3) -> Double {
    return acos(left * right / (sqrt(pow(left.x, 2) + pow(left.y, 2) + pow(left.z, 2)) * sqrt(pow(right.x, 2) + pow(right.y, 2) + pow(right.z, 2))))
}

va ^ vb

3. 自定义运算符的结合性和优先级

Ps:如果自定义了结合性和优先级,则不需要再在func前面加上infix了

precedencegroup Mypow {
    associativity: right // 右结合
    higherThan: MultiplicationPrecedence // 对应的是lowerThan
}

infix operator **: Mypow
func ** (left: Int, right: Int) -> Int{ // 注意这里的func前面不能再写infix,
    return Int(pow(Double(left), Double(right)))
}

2 ** 2 ** 3 // 256,因为是右结合

下面给出了优先级和结合性列表

Swift:运算符重载专题_第1张图片

参考网站:https://www.raywenderlich.com/650-overloading-custom-operators-in-swift

你可能感兴趣的:(Swift)