swift操作符的重载,自定义操作符

本文介绍了Swift中操作符的重载和自定义,以矩形结构体为例,展示了如何声明结构体、重载系统操作符以及自定义新的操作符。文章还探讨了`precedencegroup`的定义和操作符的结合律、优先级。通过实例,阐述了如何在实际代码中使用自定义操作符。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:
声明:转发本文,请联系作者授权

操作符的重载和自定义在objective-c上是不支持的,属于swift从别的语言中借鉴过来一种新的姿势。下面让我们一个矩形为例子一起在操作符的世界溜达一圈,一窥其中的风景吧。

声明一个矩形结构体

struct Rectangle {
    public var point:CGPoint = CGPoint.zero
    public var bouns:CGSize = CGSize.zero

    init(X x:CGFloat,Y y:CGFloat,width w:CGFloat,height h:CGFloat) {
        self.point = CGPoint.init(x: x, y: y)
        self.bouns = CGSize.init(width: w, height: h)
    }
}

重载系统已有的操作符

extension Rectangle {

    // MARK:- 重载已有操作符
    /// 比较两个矩形的面积大小
    ///
    /// - Parameters:
    ///   - lhs: 第一个矩形
    ///   - rhs: 第二个矩形
    /// - Returns: 比较结果
    static func >=(lhs:Rectangle,rhs:Rectangle) -> Bool{

        return lhs.bouns.width * lhs.bouns.height >= rhs.bouns.width * rhs.bouns.height
    }

    /// 比较两个矩形是为同一个矩形
    ///
    /// - Parameters:
    ///   - lhs: 第一个矩形
    ///   - rhs: 第二个矩形
    /// - Returns: 比较结果
    static func == (lhs:Rectangle,rhs:Rectangle) ->Bool{
        return lhs.point.equalTo(rhs.point) && lhs.bouns.equalTo(rhs.bouns)
    }

    /// 比较两个矩形是否不为同一个矩形
    ///
    /// - Parameters:
    ///   - lhs: 第一个矩形
    ///   - rhs: 第二个矩形
    /// - Returns: 比较结果
    static func != (lhs:Rectangle,rhs:Rectangle) ->Bool{
       return !(lhs == rhs)
    }
  }

自定义一个操作符

Swift中已经定义了+,-,*,/等基本运算的操作符,假如需要自定义的操作符,以自定义操作符 ^^为列子(^^定义为求出两个矩形交集区域)

precedencegroup的定义
struct PrecedenceGroup {
  enum Associativity { case left, right, none }
  let associativity: Associativity
  let higherThan: [StaticString]
  let lowerThan: [StaticString]
  let assignment :Bool
}
  • Associativity 操作符的结合律
  • higherThan 该操作符比某(系统或者自定义的)操作符的优先级高
  • lowerThan 该操作符比某个(系统或者自定义的)操作符的优先级低
  • assignment 该操作符是否为赋值操作符

定义一个操作符

precedencegroup MyPrecedence {
    lowerThan: AdditionPrecedence      
    associativity: left                 
    assignment: false                   
}
infix operator ^^: MyPrecedence  //声明操作符 ^^
  • infix 中位操作符 例如: ==>=<等操作符
  • prefix 前置操作符 例如++i!等操作符
  • postfix 后置操作符 例如i++i--

实现操作符方法

extension Rectangle {

    private func convertToRect() ->CGRect {
        return CGRect.init(origin: self.point, size: self.bouns)
    }

    static func ^^ (lhs:Rectangle,rhs:Rectangle) ->Rectangle {
        let r1:CGRect = lhs.convertToRect();
        let r2:CGRect = rhs.convertToRect();
        let result:CGRect = r1.intersection(r2)
        return Rectangle.init(X: result.minX,
                              Y: result.minY,
                              width: result.width,
                              height: result.height)
    }
}

使用

        let r1:Rectangle = Rectangle.init(X: 0, Y: 0, width: 20, height: 30)
        let r2:Rectangle = Rectangle.init(X: 0, Y: 0, width: 30, height: 30)
        let r3:Rectangle = Rectangle.init(X: 0, Y: 0, width: 20, height: 20)
        let r4:Rectangle = Rectangle.init(X: 0, Y: 0, width: 30, height: 30)
        print("r1 >= r2 is \(r1 >= r2)")
        print("r2 == r3 is \(r2 == r4)")
        print("r3 == r4 is \(r3 == r4)")
        print("r3 != r4 is \(r3 != r4)")
        print("r2 与 r3 相交的区域\(r2 ^^ r3)")

//      r1 >= r2 is false
//      r2 == r3 is true
//      r3 == r4 is false
//      r3 != r4 is true
//      r2r3 相交的区域Rectangle(point: (0.0, 0.0), bouns: (20.0, 20.0))

参考链接

https://github.com/apple/swift-evolution/blob/master/proposals/0077-operator-precedence.md

http://swifter.tips/operator/

附录:系统定义的操作符

操作符描述结合律Precedence group关键字
<<左移操作NoneBitwiseShiftPrecedence
>>右移操作NoneBitwiseShiftPrecedence
*乘法Left associativeMultiplicationPrecedence
/除法Left associativeMultiplicationPrecedence
%取余Left associativeMultiplicationPrecedence
&*乘以,忽略溢出Left associativeMultiplicationPrecedence
&按位ANDLeft associativeMultiplicationPrecedence
+加法Left associativeAdditionPrecedence
-减法Left associativeAdditionPrecedence
&+溢出加法Left associativeAdditionPrecedence
&-溢出减法Left associativeAdditionPrecedence
|位运算 orLeft associativeAdditionPrecedence
^按位异或操作Left associativeAdditionPrecedence
..<左闭右开区间NoneRangeFormationPrecedence
闭区间NoneRangeFormationPrecedence
is类型检测Left associativeCastingPrecedence
as, as?, and as!类型转换Left associativeCastingPrecedence
??nil缺省值Right associativeNilCoalescingPrecedence
<小于NoneComparisonPrecedence
<=小于或者等于NoneComparisonPrecedence
>大于NoneComparisonPrecedence
>=大于或者等于NoneComparisonPrecedence
=等于NoneComparisonPrecedence
!=不等于NoneComparisonPrecedence
===比较的是否为同一指针NoneComparisonPrecedence
!=不等于NoneComparisonPrecedence
!==比较的不是同一指针NoneComparisonPrecedence
~=模式匹配(说明)NoneComparisonPrecedence
&&逻辑ANDLeft associativeLogicalConjunctionPrecedence
||逻辑ORLeft associativeLogicalConjunctionPrecedence
?:三目运算符Right associativeTernaryPrecedence
=赋值操作Right associativeAssignmentPrecedence
*=乘等操作Right associativeAssignmentPrecedence
/=除等操作Right associativeAssignmentPrecedence
%=余等操作Right associativeAssignmentPrecedence
+=加等操作Right associativeAssignmentPrecedence
-=减等操作Right associativeAssignmentPrecedence
<<=左位移等操作Right associativeAssignmentPrecedence
>>=右位移等操作Right associativeAssignmentPrecedence
&=按位AND等操作Right associativeAssignmentPrecedence
|=按位OR等操作Right associativeAssignmentPrecedence
^=按位异或等操作Right associativeAssignmentPrecedence
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值