首页 > 代码库 > swift_重载和自定义运算符

swift_重载和自定义运算符

像这样定义一个结构体

struct Vector2D {

    var x = 0.0

    var y = 0.0

}

当 Vector2D 的两个变量相加时,我们需要这样做:

let v1 = Vector2D(x: 2.0, y: 3.0)
let v2 = Vector2D(x: 4.0, y: 5.0)
var v3 = Vector2D(x: v1.x + v2.x, y: v1.y + v2.y) 
只是一次这样的相加还好,如果需要多次重复用到这两个结构体的相加运算,就有必要重载一下 + 运算符。

func + (left: Vector2D, right: Vector2D) -> Vector2D {
    return Vector2D(x: left.x + right.x, y: left.y + right.y)
}

这样,这两个结构体相加就变得很简单了。

v3 = v1 +v2   // {x6.0, y 8.0}

重载操作使运算变得简单,但 swift 有规定:等号运算符 = 和三木运算符 (a ? b : c) 不可被重载。

当标准的操作符不满足我们的要求时,就需要自定义一些操作符。

新的操作符需要用 operator 关键字声明在全局变量中,可以用 prefix,infix,postfix 声明

例如:

  • prefixoperator? {}

现在我们定义一个新的操作符 ? 使结构体 Vector2D 做向量相乘

i infix operator ? {
    associativity none
    precedence 160
}
infix 

表示要定义的是一个中位操作符,即前后都是输入

associativity 

定义了结合律,即如果多个同类的操作符顺序出现的计算顺序。比如常见的加法和减法都是 left,就是说多个加法同时出现时按照从左往右的顺序计算 (因为加法满足交换律,所以这个顺序无所谓,但是减法的话计算顺序就很重要了)。点乘的结果是一个 Double,不再会和其他点乘结合使用,所以这里写成 none;详见:这里

precedence

运算的优先级,越高的话优先进行计算。swift 中乘法和除法的优先级是 150 ,加法和减法的优先级是 140 ,这里我们定义点积的优先级为 160 ,就是说应该早于普通的乘除进行运算。

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

let value = http://www.mamicode.com/v1 ? v2 // 23.0

这样就可以进行向量的点积运算了。

参考资料:
Advanced Operators
造个类型不是梦-白话swift类型创建

swift_重载和自定义运算符