作者:
![]()
声明:转发本文,请联系作者授权
操作符的重载和自定义在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
// r2 与 r3 相交的区域Rectangle(point: (0.0, 0.0), bouns: (20.0, 20.0))
参考链接
https://github.com/apple/swift-evolution/blob/master/proposals/0077-operator-precedence.md
附录:系统定义的操作符
| 操作符 | 描述 | 结合律 | Precedence group关键字 |
|---|---|---|---|
| << | 左移操作 | None | BitwiseShiftPrecedence |
| >> | 右移操作 | None | BitwiseShiftPrecedence |
| * | 乘法 | Left associative | MultiplicationPrecedence |
| / | 除法 | Left associative | MultiplicationPrecedence |
| % | 取余 | Left associative | MultiplicationPrecedence |
| &* | 乘以,忽略溢出 | Left associative | MultiplicationPrecedence |
| & | 按位AND | Left associative | MultiplicationPrecedence |
| + | 加法 | Left associative | AdditionPrecedence |
| - | 减法 | Left associative | AdditionPrecedence |
| &+ | 溢出加法 | Left associative | AdditionPrecedence |
| &- | 溢出减法 | Left associative | AdditionPrecedence |
| | | 位运算 or | Left associative | AdditionPrecedence |
| ^ | 按位异或操作 | Left associative | AdditionPrecedence |
| ..< | 左闭右开区间 | None | RangeFormationPrecedence |
| … | 闭区间 | None | RangeFormationPrecedence |
| is | 类型检测 | Left associative | CastingPrecedence |
| as, as?, and as! | 类型转换 | Left associative | CastingPrecedence |
| ?? | nil缺省值 | Right associative | NilCoalescingPrecedence |
| < | 小于 | None | ComparisonPrecedence |
| <= | 小于或者等于 | None | ComparisonPrecedence |
| > | 大于 | None | ComparisonPrecedence |
| >= | 大于或者等于 | None | ComparisonPrecedence |
| = | 等于 | None | ComparisonPrecedence |
| != | 不等于 | None | ComparisonPrecedence |
| === | 比较的是否为同一指针 | None | ComparisonPrecedence |
| != | 不等于 | None | ComparisonPrecedence |
| !== | 比较的不是同一指针 | None | ComparisonPrecedence |
| ~= | 模式匹配(说明) | None | ComparisonPrecedence |
| && | 逻辑AND | Left associative | LogicalConjunctionPrecedence |
| || | 逻辑OR | Left associative | LogicalConjunctionPrecedence |
| ?: | 三目运算符 | Right associative | TernaryPrecedence |
| = | 赋值操作 | Right associative | AssignmentPrecedence |
| *= | 乘等操作 | Right associative | AssignmentPrecedence |
| /= | 除等操作 | Right associative | AssignmentPrecedence |
| %= | 余等操作 | Right associative | AssignmentPrecedence |
| += | 加等操作 | Right associative | AssignmentPrecedence |
| -= | 减等操作 | Right associative | AssignmentPrecedence |
| <<= | 左位移等操作 | Right associative | AssignmentPrecedence |
| >>= | 右位移等操作 | Right associative | AssignmentPrecedence |
| &= | 按位AND等操作 | Right associative | AssignmentPrecedence |
| |= | 按位OR等操作 | Right associative | AssignmentPrecedence |
| ^= | 按位异或等操作 | Right associative | AssignmentPrecedence |
本文介绍了Swift中操作符的重载和自定义,以矩形结构体为例,展示了如何声明结构体、重载系统操作符以及自定义新的操作符。文章还探讨了`precedencegroup`的定义和操作符的结合律、优先级。通过实例,阐述了如何在实际代码中使用自定义操作符。
3万+

被折叠的 条评论
为什么被折叠?



