• Swift-----运算符重载


    1. 现有一个向量,我们重载它的“+”、“-”、“*”、“+=”运算符。

     注意: “=”是不可以进行重载的。

    struct Vector3 {
        
        var x: Double = 0.0
        var y: Double = 0.0
        var z: Double = 0.0
    
    }
    
    // 重载加号(+)
    func + (left: Vector3, right: Vector3) -> Vector3 {
        return Vector3(x: left.x + right.x, y: left.y + right.y, z: left.z + right.z)
    }
    
    // 重载减号(-)
    func - (left: Vector3, right: Vector3) -> Vector3 {
        return Vector3(x: left.x - right.x, y: left.y - right.y, z: left.z - right.z)
    }
    
    // 重载乘号(*)
    func *(left: Vector3, right: Vector3) -> Double {
        return left.x * right.x + left.y * right.y + left.z * right.z
    }
    
    // 重载负号(-),只有一个参数  由于不知道“-”是放在参数的左侧还是右侧,故需要添加关键字prefix,代表“-”是在参数的左侧
    prefix func - (value: Vector3) -> Vector3 {
        return Vector3(x: -value.x, y: -value.y, z: -value.z)
    }
    
    // 重载 +=  由于是把该操作会使left值发生改变,故left需要用到关键字 inout;由于“+”方法在之前定义过,故在这个方法中可以直接使用“+”方法。
    func += (left: inout Vector3, right: Vector3){
        left = left + right
    }
    
    var v1 = Vector3(x: 1, y: 1, z: 1)
    let v2 = Vector3(x: 3, y: 4, z: 5)
    
    v1 + v2  // {x: 4, y: 5, z: 6}
    v1 - v2  // {x: -2, y: -3, z: -4}
    v1 * v2  // 12
    -v1    // {x: -1, y: -1, z: -1}
    
    v1 += v2  
    v1    // {x: 4, y: 5, z: 6}

     2. 重载比较运算符

    func == (left: Vector3, right: Vector3) -> Bool {
        return left.x == right.x && left.y == right.y && left.z == right.z
    }
    
    func != (left: Vector3, right: Vector3) -> Bool {
        return !(left == right)
    }
    
    func > (left: Vector3, right: Vector3) -> Bool {
        
        if left.x != right.x {return left.x > right.x}
        if left.y != right.y {return left.y > right.y}
        if left.z != right.z {return left.z > right.z}
        
        return false
    }
    
    func >= (left: Vector3, right: Vector3) -> Bool {
        return left > right || left == right
    }
    
    func < (left: Vector3, right: Vector3) -> Bool {
        return !(left >= right)
    }
    
    var v1 = Vector3(x: 1, y: 1, z: 1)
    let v2 = Vector3(x: 3, y: 4, z: 5)
    
    v1 == v2  // false
    v1 != v2  // true
    v1 > v2   // false
    v1 >= v2  // false
    v1 < v2   // true

     3 自定义运算符

    (1)对向量定义一个“+++”运算符,类似Int中的“++”运算符

    // 对于系统中没有的运算符,需要通过 operator 来定义操作符,prefix表示操作符应在参数的前面
    prefix
    operator +++ prefix func +++ (vector: inout Vector3) -> Vector3 { let vec = vector vector += Vector3(x: 1.0, y: 1.0, z: 1.0) return vec } // postfix表示操作符应在参数的后面 postfix operator +++ postfix func +++ (vector: inout Vector3) -> Vector3 { vector += Vector3(x: 1.0, y: 1.0, z: 1.0) return vector } var vector1 = Vector3(x: 1, y: 2, z: 3) // {x: 1, y: 2, z: 3} vector1+++                   // {x: 2, y: 3, z: 4} vector1                     // {x: 2, y: 3, z: 4} var vector2 = Vector3(x: 1, y: 2, z: 3) // {x: 1, y: 2, z: 3} +++vector2                   // {x: 1, y: 2, z: 3} vect                      // {x: 2, y: 3, z: 4}

    (2) 自定义一个中间运算符 infix

    struct Vector3 {
        
        var x: Double = 0.0
        var y: Double = 0.0
        var z: Double = 0.0
        
        func length() -> Double {
            return sqrt(x * x + y * y + z * z)
        }
    }
    
    // 重载乘号(*)
    func *(left: Vector3, right: Vector3) -> Double {
        return left.x * right.x + left.y * right.y + left.z * right.z
    }
    
    var vector3 = Vector3(x: 1, y: 2, z: 3)
    var vector4 = Vector3(x: 2, y: 5, z: -3)
    
    /*
    在 swift 2 中自定义操作符
    infix operator ^ {
        associativity left    // 左结合
        precedence 145    // 加法是140, 乘法是150. 默认是140。表示优先级高于加法,低于乘法
    }
    */
    
    // 在Swift 3 中上面的定义会出现警告信息:Operator should no longer be declared with body;use a precedence group instead
    // 在Swift 3 中应该如下自定义操作符
    infix operator ^: ATPrecedence
    precedencegroup ATPrecedence {
        associativity: left                 // 表示左结合
        higherThan: AdditionPrecedence      // AdditionPrecedence表示加法,优先级高于加法
        lowerThan: MultiplicationPrecedence // MultiplicationPrecedence表示乘法,优先级低于乘法
    }
    
    func ^(left: Vector3, right: Vector3) -> Double {
        return acos((left * right) / (left.length() * right.length()))
    }
    
    vector3 ^ vector4
    infix operator **: BTPrecedence
    precedencegroup BTPrecedence {
        associativity: left        // 左结合
        higherThan: AdditionPrecedence  // 优先级高于加法运算符
    }
    
    func **(x: Double, y: Double) -> Double {
        return pow(x, y)
    }
    
    2 ** 3 ** 2     // 64
    1 + 2 ** 3 ** 2 // 65
    infix operator **: BTPrecedence
    precedencegroup BTPrecedence {
        associativity: right      //右结合
        lowerThan: AdditionPrecedence // 优先级低于加法运算符
    }
    
    func **(x: Double, y: Double) -> Double {
        return pow(x, y)
    }
    
    2 ** 3 ** 2     // 512
    1 + 2 ** 3 ** 2  //19683
  • 相关阅读:
    Visual Studio的输出窗口上输出调试信息的函数
    std::min error C2059: 语法错误:“::” 的解决方法
    error C2872: “flann”: 不明确的符号 --- PCL 与OpenCV2 的flann命名空间冲突问题的解决方法
    VS编译器中设置 输出窗口 只显示error,不显示warning 要如何配置
    nginx.conf的完整配置说明
    Nginx基本配置、性能优化指南
    Apache手册
    Apache 配置虚拟主机三种方式
    Linux常用命令汇总
    Linux下安装Apache
  • 原文地址:https://www.cnblogs.com/muzijie/p/6591045.html
Copyright © 2020-2023  润新知