Swift之运算符重载

作者: 大刘 | 来源:发表于2022-06-27 09:08 被阅读0次

    Created by 大刘 liuxing8807@126.com

    在C++中, 运算符是可以重载的, Swift也是支持的

    注:=和三目运算符a ? b : c不可重载

    重载双目运算符

    class Vector {
        var x: Double = 0.0
        var y: Double = 0.0
        var z: Double = 0.0
        
        init(x: Double, y: Double, z: Double) {
            self.x = x
            self.y = y
            self.z = z
        }
        
        convenience init() {
            self.init(x: 0, y: 0, z: 0) 
        }
        
        /// Operator '+' declared in type 'Vector' must be 'static'
        /// + 是双目运算符,两个参数
        static func +(v1: Vector, v2: Vector) -> Vector {
            let vector: Vector = Vector()
            vector.x = v1.x + v2.x
            vector.y = v1.y + v2.y
            vector.z = v1.z + v2.z
            return vector
        }
    }
    

    单目运算符

    类和结构体也可以实现单目运算符,单目运算符只运算一个值。
    运算符出现在值之前为前缀运算符(prefix, 如 -a),出现在值之后为后缀运算符(postfix, 如a!)。

    struct Coordinate {
        var x: Double = 0.0
        var y: Double = 0.0
        
        static prefix func +(coordinate: Coordinate) -> Coordinate {
            return Coordinate(x: +coordinate.x, y: +coordinate.y)
        }
        
        static prefix func -(coordinate: Coordinate) -> Coordinate {
            return Coordinate(x: -coordinate.x, y: -coordinate.y)
        }
    }
    
    func test() {
        let p1 = Coordinate(x: 1.0, y: 1.0)
        let p2 = Coordinate(x: 2.0, y: 2.0)
        print(-p1) // Coordinate(x: -1.0, y: -1.0)
        print(+p2) // Coordinate(x: 2.0, y: 2.0)
    }
    

    复合赋值运算符

    复合赋值运算符是赋值运算符(=)和其他运算符进行结合, 如 +=、-=

    struct Coordinate {
        var x: Double = 0.0
        var y: Double = 0.0
        
        // 如果放在全局函数里, 不需要加static, 否则, static不可省略
        static func +=(left: inout Coordinate, right: Coordinate) {
            left = Coordinate(x: left.x + right.x, y: left.y + right.y)
        }
        
        static func -=(c1: inout Coordinate, c2: Coordinate) {
            left = Coordinate(x: left.x - right.x , y: left.y - right.y)
        }
    }
    
    func test() {
        var p1 = Coordinate(x: 1.0, y: 1.0)
        let p2 = Coordinate(x: 2.0, y: 2.0)
        p1 += p2
        print(p1) // Coordinate(x: 3.0, y: 3.0)
    }
    

    等价运算符 ==

    自定义类和结构体没有对等价运算符进行默认的实现。等价运算符一般被称为相等运算符==和不等运算符 !=

    struct Coordinate {
        var x: Double = 0.0
        var y: Double = 0.0
        
        static func ==(c1: Coordinate, c2: Coordinate) -> Bool {
            return c1.x == c2.x && c1.y == c2.y
        }
        
        static func !=(left: Coordinate, right: Coordinate) -> Bool {
            return left.x != right.x || left.y != right.y
        }
    }
    
    func test() {
        let p1 = Coordinate(x: 1.0, y: 1.0)
        var p2 = Coordinate(x: 2.0, y: 2.0)
        
        print(p1 == p2) // false
        p2.x -= 1
        p2.y -= 1
        print(p1 == p2) // true
    }
    

    自定义运算符

    可以自定义前置运算符prefix、后置运算符postfix、中置运算符infix, 约束条件:

    1. 只能使用如下字符:
      - + * / = % < > ! & | ^ . ~
    2. 只有中置运算符可以继承优先级组 precdence(后面介绍)
    3. 自定义运算符不可放在类中,必须放在文件作用域中

    自定义后置运算符

    struct Coordinate {
        var x: Double = 0.0
        var y: Double = 0.0
    }
    
    // 文件作用域,即全局作用域,不可在class下
    prefix operator +++
    prefix func +++(coordinate: inout Coordinate) -> Coordinate {
        coordinate.x = coordinate.x + coordinate.x
        coordinate.y = coordinate.y + coordinate.y
        return coordinate
    }
    
    func test() {
        var p1 = Coordinate(x: 1.0, y: 1.0)
        print(+++p1) // Coordinate(x: 2.0, y: 2.0)
    }
    

    自定义前置运算符和自定义后置运算符类似

    postfix operator +++
    postfix func +++(coordinate: inout Coordinate) -> Coordinate {
        coordinate.x = coordinate.x + coordinate.x
        coordinate.y = coordinate.y + coordinate.y
        return coordinate
    }
    

    自定义中置运算符

    precedencegroup MyPrecedence {
        // higherThan: AdditionPrecedence   // 优先级, 比加法运算高
        lowerThan: AdditionPrecedence       // 优先级, 比加法运算低
        associativity: none                 // 结合方向:left, right or none
        assignment: false                   // true代表是赋值运算符,false代表非赋值运算符
    }
    
    infix operator +++ : MyPrecedence  // 继承 MyPrecedence 优先级组(可选)
    func +++(left: Int, right: Int) -> Int {
        return (left + right) * 2
    }
    
    func test() {
        print(3+++2)
    }
    

    借助自定义运算符,我们可以浪一浪,定义一个操作符,当有值是使用此值,无值时使用想要的默认值,如下所示:

    postfix operator <<<
    postfix func <<<(a: String?) -> String { return a ?? "" }
    
    func test() {
        print(getStr()<<<)
    }
    
    func getStr() -> String? {
        return nil
    }
    

    示例

    postfix operator <<<
    
    postfix func <<<(a: String?)              -> String              { return a ?? "" }
    postfix func <<<(a: Int?)                 -> Int                 { return a ?? 0 }
    postfix func <<<(a: Int8?)                -> Int8                { return a ?? 0 }
    postfix func <<<(a: Int16?)               -> Int16               { return a ?? 0 }
    postfix func <<<(a: Int32?)               -> Int32               { return a ?? 0 }
    postfix func <<<(a: Int64?)               -> Int64               { return a ?? 0 }
    postfix func <<<(a: UInt?)                -> UInt                { return a ?? 0 }
    postfix func <<<(a: Double?)              -> Double              { return a ?? 0.0 }
    postfix func <<<(a: Float?)               -> Float               { return a ?? 0.0 }
    postfix func <<<(a: [AnyObject]?)         -> [AnyObject]         { return a ?? [] }
    postfix func <<<(a: [String]?)            -> [String]            { return a ?? [] }
    postfix func <<<(a: [Int]?)               -> [Int]               { return a ?? [] }
    postfix func <<<(a: [String: AnyObject]?) -> [String: AnyObject] { return a ?? [:]}
    postfix func <<<(a: [String: String]?)    -> [String: String]    { return a ?? [:] }
    

    相关文章

      网友评论

        本文标题:Swift之运算符重载

        本文链接:https://www.haomeiwen.com/subject/vrynvrtx.html