在编程过程中,我们必定经常用到 +、-、=、(a ? b :c)等操作符号,使用起来相当方便。
但是在一些自定义的 struct 或者 class 中,系统并没有提供相应方法,操作起来就相对复杂。
- 比如我们有一个自定义的向量 Vector2D
struct Vector2D {
var x = 0.0, y = 0.0
}
- 现在有向量 one 和向量 two,我们想有一个两个向量相加的方法,我们可以这样做
extension Vector2D {
func add(_ other: Vector2D) -> Vector2D {
return Vector2D(x: self.x + other.x, y: self.y + other.y)
}
}
//然后使用的时候这样调用
let one = Vector2D(x: 1, y: 1)
let two = Vector2D(x: 2, y: 2)
let result = one.add(two)
- 看起来也相对清晰,调用起来也没那么复杂,但是 我们还能不能更加优化呢,比如这样
let result = one + two
这时候,我们就需要重载 + 这个操作符了,因为是系统定义过的,所以使用的时候,直接重载就可以了。(然后我们就可以像上面这样调用了)
extension Vector2D {
static func +(left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: left.x + right.x, y: left.y + right.y)
}
}
- 现在我们又有了新需求,先两个相加,然后取反,我们想定义一个操作符 -+,怎么处理呢
extension Vector2D {
static func -+(left: Vector2D, right: Vector2D) -> Vector2D {
return Vector2D(x: -(left.x + right.x), y: -(left.y + right.y))
}
}
你会发现,这样写完之后,Xcode 开始报错 Operator implementation without matching operator declaration 说我们没有声明这个运算符,那么我们声明一下就可以了嘛
infix operator -+ : AdditionPrecedence
这里来解释一下什么的含义
- infix :这是在将 -+ 声明为一个 中位 操作符,即 -+ 前后都是有参数的。相应的操作符有 prefix(前位, 如 -- a 中的 --) 和 postfix(后位, 如 a++ 中的 ++)
- operator : 这是 -+ 申明位操作符的关键字
- AssignmentPrecedence : 这是优先级,现在这个是 和加减优先级相同
当然,我们也可以自定义优先级
infix operator -+ : VectorPrecedence
precedencegroup VectorPrecedence {
associativity: none
higherThan: AdditionPrecedence
lowerThan: MultiplicationPrecedence
}
- associativity : 是结合律,是指,出现相同优先级的运算符之后,是从左往右算还是从右往左算,参数为 left , right , none 。这里因为只有这个自己用到了这个优先级,所以这里写哪个都无所谓。
- higherThan : 直接字面意思理解,就是优先级高于哪个优先级
- lowerThan : 和上面 higherThan 相同,低于哪个优先级
系统优先级这里有一张表

- 你也可以直接到苹果官网查看 https://developer.apple.com/documentation/swift/swift_standard_library/operator_declarations
回到标题, 1+1 怎么能等于 3 呢
extension Int {
static func +(left: Int, right: Int) -> Int {
return 3
}
}
- 此时,当你再次去计算 1+1 的时候 ,结果就是3了 (哈哈,其实只要加法计算就都会等于 3 了)
注意:这里只是开玩笑用一下,实际项目中可千万别这样写,会坑死队友的
。
注意: 在操作符定义中,千万不能使用正在定义的操作符,会无限递归的!
网友评论