Swift 操作符
Swift 支持重载操作符的特性,让我们可以自定义一些简单的计算。
最经典的例子就是两个二维向量之间的计算了。
首先我们定义一个二维向量,并创建两个向量
1 | struct Vector2D { |
相加两个向量:
1 | let v3 = Vector2D(x: v1.x + v2.x, y: v1.y + v2.y) |
这样一次的话,感觉还好。但是遇到复杂的运算的话,这样写感觉就太啰嗦了,这时候重载操作符是最好的选择。
1 | func +(left: Vector2D, right: Vector2D) -> Vector2D { |
这样,我们相加两个向量就简单的多了
1 | let v3 = v1 + v2 |
向量的内积运算符API中是没有定义的,所以我们自定义一个内积运算符。
这里是Swift 3的实现方式(感觉看起来比之前的版本可读性好多了)。
1 | // 自定义操作符 别名类型 |
接下来我们就可以写具体的运算实现了
1 | func +*(left: Vector2D, right: Vector2D) -> Double { |
precedencegroup
定义了一个操作符优先级别。操作符优先级的定义和类型声明有些相似,一个操作符比需要属于某个特定的优先级。Swift 标准库中已经定义了一些常用的运算优先级组,比如加法优先级 (AdditionPrecedence) 和乘法优先级 (MultiplicationPrecedence) 等,你可以在这里找到完整的列表。如果没有适合你的运算符的优先级组,你就需要像我们在例子中做得这样,自己指定结合律方式和优先级顺序了。
infix
表示要定义的是一个中位操作符,即前后都是输入;其他的修饰还包括 prefix 和 postfix,不再赘述
associativity
定义了结合律,即如果多个同类的操作符顺序出现的计算顺序。比如常见的加法和减法都是 left,就是说多个加法同时出现时按照从左往右的顺序计算 (因为加法满足交换律,所以这个顺序无所谓,但是减法的话计算顺序就很重要了)。点乘的结果是一个 Double,不再会和其他点乘结合使用,所以这里写成 none
higherThan
运算的优先级,点积运算是优先于乘法运算的。除了 higherThan,也支持使用 lowerThan 来指定优先级低于某个其他组。