一、为什么要重载运算符
我们都知道所谓的运算符平常的也就是 + - * /
之类的,比如我们随便写个 1 + 2
打印肯定输出的是 3
,那么我们为什么还要重载运算符呢?下面我们就举个例子,如下我定义个结构体
1 2 3 4 5 6 |
struct Vector { var x: Int = 0 var y: Int = 0 var z: Int = 0 } |
然后我们定义两个变量 V1,V2
1 2 |
var V1 = Vector(x: 1, y: 2, z: 3) var V2 = Vector(x: 4, y: 5, z: 6) |
然后我们来写V1 + V2
,报错
报错 +
不能用于 Vector
,这是因为 Vector
使我们自定义的一个结构体,所以编译器不知道我们要用 +
对这个结构体做什么操作。因此,在这里我们就需要用到运算符的重载。
二、如何重载运算符
- 1、含有两个参数的运算符的重载
因为运算符是一个函数,比如对于数组的reduce
方法我们就可以如下
12let arr = [1, 2, 3, 4]arr.reduce(0, +)
结果是 10 ,这里的+
就代表了一个函数,所以我们重新写的时候可以如下
1234func + (left: Vector, right: Vector) -> Vector {return Vector(x: left.x + right.x, y: left.y + right.y, z: left.z + right.z)}
这样我们就实现了+
的重载,上面函数中 left 和 right 两个参数都是 Vector 类型的,一个表示运算符左边的参数一个表示运算符右边的参数(这两个参数是有先后顺序的,由于加法满足加法交换律所以这里体现不出来,有兴趣的可以试一下-
的重载,这时候就要注意顺序了),然后返回值得类型也是 Vector 类型,再来实现V1 + V2
的时候,就发现得到了一个新的 Vector 类型的值
这里我们就已经完成了 +
这个运算符的重载。当然有兴趣的童鞋还可以试着自己实现 -
或者 *
的重载,这里就不一一举例了。
关于双目运算符的重载,和单目运算符类似,如下
1 2 3 4 |
func += (left: inout Vector, right: Vector) { left = left + right } |
运行结果
- 2、含有一个参数的运算符的重载
照着上面单目运算符的方式我们自己来写个-
重载例子,如下
1234func - (vector: Vector) -> Vector {return Vector(x: -vector.x, y: -vector.y, z: -vector.z)}
按照我们的逻辑这里取反逻辑上应该是正确的,可是编译会发现报错
这里我们就要注意了,和有两个参数的运算符不同的是,只有一个参数的运算符位置是不固定的,这里的 -
可以在前可以在后,所以我们在这里还需要注意运算符的位置
1 2 3 4 |
prefix func - (vector: Vector) -> Vector { return Vector(x: -vector.x, y: -vector.y, z: -vector.rayon-o">: -vector.y, z: -vector.crayon-5812c90234e0d201141076" class="crayon-syntax crayon-theme-github crayon-font-monaco crayon-os-pc print-yes notranslate" data-settings=" minimize scroll-always" style=" margin-top: 12px; margin-bottom: 12px; font-size: 13px !important; line-height: 15px !important;">
然后我们定义两个变量 V1,V2
然后我们来写 报错 二、如何重载运算符
这里我们就已经完成了
运行结果
这里我们就要注意了,和有两个参数的运算符不同的是,只有一个参数的运算符位置是不固定的,这里的
|