一.什么是运算符重载
运算符重载就是将 + - * / == != 等数学运算符看成函数的一种技术
二.看看demo
//:# 运算符重载
//类 结构体 枚举可以为现有的运算符提供自定的视实现,这个操作叫做运算符重载
struct Point : Equatable, Comparable{
static func < (lhs: Point, rhs: Point) -> Bool {
true
}
var x = 0, y = 0
//默认中缀, + 在连个参数中间
static func + (_ p1: Point, _ p2: Point) -> Point{
Point(x: p1.x + p2.x, y: p1.y + p2.y)
}
//前缀, - 在参数之前
static prefix func - (_ p1: Point) -> Point{
Point(x: -p1.x, y: -p1.y)
}
//后缀, ++ 在参数之后
static postfix func ++ (p: inout Point) {
p.x += 1
p.y += 1
}
//如果遵守了Equatable协议,皆可以实现这个方法
static func == (lhs: Point, rhs: Point) -> Bool {
lhs.y == rhs.y//如果两个y值相等,则返回true
}
}
// 也可以创建一个函数来实现, 但是必须是全局的, 设计不好. 而且不支持前缀和后缀
//func + (_ p1: Point, _ p2: Point) -> Point{
// Point(x: p1.x + p2.x, y: p1.y + p2.y)
//}
let p1 = Point(x: 10, y: 10)
let p2 = Point(x: 20, y: 20)
let add: Point = p1 + p2
print(add)//Point(x: 30, y: 30)
var sub = -add
print(sub)//Point(x: -30, y: -30)
sub++
print(sub)//Point(x: -29, y: -29)
//Equatable协议
//1.只要你实现了==, 系统会自动为你实现!=
//2.针对没有关联值的枚举,系统会自动为你加上Equatable协议,你可以直接使用== 和 !=
//3.针对有关联值的枚举,但是关联值页遵守了Equatable协议,那么该枚举也可以直接使用== 和 !=
//4.结构体,只拥有存储属性并且该存储属性遵守了Equatable协议,那么该结构体也可以直接使用== 和 !=
//5.类(引用类型),判断是否是同一对象,需要使用 === 或者 !==
//Comparable协议
//系统帮我们实现了 < <= > >= 等运算符重载
//:# 自定义运算符(Custom Operator)
//可以自定义新的运算符: 在全局作用域使用operator进行声明
//前缀运算符
prefix operator ++++
prefix func ++++ (_ a: inout Int) {
a += 1
}
var a = 10
++++a
print(a)//11
//后缀运算符
postfix operator ---
//中缀运算符 挺复杂的,得再查查资料
//infix operator -+- :
三. === ==是个啥
let int: Int = 10
struct stu1 {}
class cls1{}
struct stu2: Equatable{var x: Int=0}
class cls2: Equatable{
//如果一个类实现了Equatable协议,而又没有实现,则会报下面的错
//Type 'cls2' does not conform to protocol 'Equatable'
static func == (lhs: cls2, rhs: cls2) -> Bool {
return true
}
}
//两个结构体判断相等,报错了
//let stu1_0 = stu1()
//let stu1_1 = stu1()
//stu1_0 == stu1_1//Binary operator '==' cannot be applied to two 'stu1' operands
//两个class判断相等,没有报错,而且还能使用===
//这是因为 所有类都隐式地遵循 AnyObject,系统帮我们实现了===这个函数
//@inlinable public func === (lhs: AnyObject?, rhs: AnyObject?) -> Bool (misc模块)
let cls1_0 = cls1()
let cls1_1 = cls1()
cls1_0 === cls1_1 //false
let stu2_0 = stu2(x:10)
let stu2_1 = stu2(x:20)
let stu2_2 = stu2(x:10)
stu2_0 == stu2_1 //false
stu2_0 == stu2_2 //true
总结:
- 如果结构体没有实现Equable协议,是不能使用
==
的,会报错。 - 结构体实现了Equable协议,如果没有具体的实现函数, 那么系统会帮我们判断结构体里面的数据是否一致。 如果实现了,那么就会用我们自己的方法
- 对于类, 天生自带
===
方法,这是用来判断内存地址是否一样的。 如果想使用==
, 那么需要自己实现Equable协议。
总的来说:
===
只针对class
==
结构体可以用, class也可以用