在 Swift 中定义自己的运算符

Swift 可以支持定义自己的运算符,这样给程序提供了更多的灵活性。

自定义运算符

  • 除了实现标准运算符,在 Swift 当中还可以声明和实现自定义运算符(custom operators)
  • 新的运算符要在全局作用域内,使用 operator 关键字进行声明,同时还要指定 prefix、infix 或者 postfix 限定符。

自定义中追运算符的优先级和结合性

  • 自定义的中缀 infix 运算符也可以指定优先级和结合性
  • 每一个自定义的中缀运算符都属于一个优先级组
  • 优先级组指定了自定义中缀运算符和其他中缀运算符的关系

示例

实现一个 +++ 运算符,再一个 +- 的运算符,然后再实现一个 *^ 的运算符,代码如下:

prefix operator +++
extension Vector2D {
    static prefix func +++ (vector: inout Vector2D) -> Vector2D {
        vector += vector
        return vector
    }
}

var vector11 = Vector2D(x: 2.0, y: 4.0)
let newVector11 = +++vector11
// vector11 x is 4.0, y is 8.0
print("vector11 x is \(vector11.x), y is \(vector11.y)")
// newVector11 x is 4.0, y is 8.0
print("newVector11 x is \(newVector11.x), y is \(newVector11.y)")

// 定义了一个前缀运算符
// 该运算符属于 加法优先组,该组属于系统提供的组
infix operator +-: AdditionPrecedence

extension Vector2D {
    // 该运算符实现 x 的相加,y 的相减
    static func +- (left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y - right.y)
    }
}

// 定义了一个中缀运算符
// 该运算符属于 乘法优先组,该组属于系统提供的组
infix operator *^: MultiplicationPrecedence

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

let firstVector = Vector2D(x: 1.0, y: 2.0)
let secondVector = Vector2D(x: 3.0, y: 7.0)
let thirdVector = Vector2D(x: 2.0, y: 2.0)

let vector22 = firstVector +- secondVector *^ thirdVector
// vector22 x is 7.0, y is -51.0
print("vector22 x is \(vector22.x), y is \(vector22.y)")

在代码中计算 firstVector +- secondVector *^ thirdVector 时,要先进行 secondeVector 和 thirdVector 的 *^ 计算,再进行 firstVector 的 +- 运算。因为 MultiplicationPrecedence 的优先级高于 AdditionPrecedence 的优先级。

下面来修改一下上面优先级的情况,代码如下:

// infix operator *^: MultiplicationPrecedence

// *^ 的优先级组是自定义的优先级组
infix operator *^: MyPrecedence
// 该自定义的优先级组的优先级低于 AdditionPrecedence
precedencegroup MyPrecedence {
    associativity: left
    lowerThan: AdditionPrecedence
}

let vector22 = firstVector +- secondVector *^ thirdVector
// vector22 x is 8.0, y is 29.0
print("vector22 x is \(vector22.x), y is \(vector22.y)")

在修改了优先级组以后,可以发现最后的运算结果发生了变化。



我的微信公众号:“码农UP2U”

推荐阅读更多精彩内容