作者:
![]()
声明:转发本文,请联系作者授权
操作符的重载和自定义在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 |