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,因为是右结合
下面给出了优先级和结合性列表