Swift 可选项的本质、 运算符重载 、扩展

Swift 可选项的本质、 运算符重载 、扩展

类、结构体、枚举可以为现有的运算符提供自定义的实现,这个操作叫做运算符重载

重载:函数名相同,功能不同

func sum(v1, v2)
func sum(v1, v2, v3)


/// 点
struct Point{
    var x = 0, y = 0
    static func + (p1: Point, p2: Point) -> Point {
        print("p1: \(p1) + p2: \(p2)的操作")
        return Point(x: p1.x + p2.x, y: p1.y + p2.y)
    }
    static func - (p1: Point, p2: Point) -> Point {
        print("p1: \(p1) - p2: \(p2)的操作")
        return Point.init(x: p1.x - p2.x, y: p1.y - p2.y)
    }
    static prefix func - (p: Point) -> Point{
        return Point(x: -p.x, y: -p.y)
    }
    static func += (p1: inout Point, p2: Point){
        p1 = p1 + p2
    }
    static prefix func ++ (p: inout Point) -> Point {
        p += Point(x: 1, y: 1)
        return p
    }
    static postfix func ++ (p: inout Point) -> Point {
        let temp = p
        p += temp
        return temp
    }
    static func == (p1: Point, p2: Point) -> Bool {
        p1.x == p2.x && p1.y == p2.y
    }
}

//重载(结合性)
var p1 = Point.init(x: 1, y: 1)
var p2 = Point.init(x: 2, y: 2)
var p3 = Point.init(x: 3, y:  )

var p4 = p1 + p2 + p3
print(p4)

Equatable 等价性

要想得知2个实例是否等价,一般的做法是遵守Equable协议,重载 == 运算符
与此同时,等价于重载了!=
Swift为以下类型提供默认的Equatable 实现

没有关联类型的枚举 (关联类型中不确定比较什么)

class Cat{}
enum Answer{
	case wrong(Cat)
	case right
}

只拥有遵守Equatable 协议关联类型的枚举

enum Answer: Equatable{
	case wrong(Int)  //Int 本身遵守Eqautable
	case right
}

只拥有遵守Equatable 协议存储属性的结构体

引用类型比较存储的地址值是否相等(是否引用这同一个对象),
使用恒等运算符

===!==
var p1 = Person(age: 10)
var p2 = Person(age: 10)
print(p1 === p2)//比较地址值

Comparable 比较大小

相比较2个实例的大小,一般的做法是:
1、遵守Comparable 协议
2、重载相应的运算符
//score 大的比较大,若score相等,age小的比较大

struct Student: Comparable{
	var age: Int
	var score: Int
	init(score: Int, age: Int){
		self.age = age
		self.score = score
}
	static func < (lhs: Student, rhs: Student) -> Bool {
		(lhs.score < rhs.score) || ( lhs.score == rhs.score && lhs.age > 			rhs.age)
	}
	static func > (lhs: Student, rhs: Student) -> Bool{
		(lhs.score > rhs.score) || (lhs.score == rhs.score && lhs.age < 	rhs.age)
	}
	static func <= (lhs: Student, rhs: Student) -> Bool {
		!(lhs > rhs)
	}
	static func >= (lhs: Student, rhs: Student) -> Bool {
		!(lhs < rhs)
	}
}

自定义运算符(Custom Operator)

可自定义新的运算符:在全局作用域使用operator 进行声明

prefix operator 前缀运算符
postfix operator  后缀运算符
infix operator 中缀运算符 : 优先级组
precedemcegroup 优先级组 {
	associativity: 结合性(left\right\nonehigherThan: 比谁的优先级高
	lowerThan: 比谁的优先级低
	assignment: true 代表可选链操作中拥有跟赋值运算符一样的优先级 (如果是赋值运算符怎么思考)
}

扩展(Extension)

Swift 中的扩展,有点类似与OC中的分类 (Category)

扩展可以为枚举、结构体、类、协议添加新功能

可以添加方法、计算属性、下标、(便捷)初始化器、嵌套类型、协议等等

扩展不能办到的功能

1、不能覆盖原有功能
2、不能添加存储属性,不能向已有的属性添加属性观察器
3、不能添加父类
4、不能添加指定初始化器(init),添加反初始化器(deinit)

  • 如果希望自定义初始化器的同时,编译器也能生成默认的初始化器
  • 可以 在 扩展 中编写自定义初始化器,
  • 类遵守协议实现的require初始化器,不能写在扩展中
  • 类 的扩展中可以增加便捷初始化器
  • require 初始化器也不能写在扩展中

协议 给协议添加扩展

如果一个类型已经是吸纳了协议的所有要求,但是还没有声明它遵守了这个协议

可以通过扩展来让它遵守这个协议
  • 扩展可以给协议提供默认实现,也间接实现【可选协议】的效果 (协议的默认所有的方法必须实现)
  • 扩展可以给协议扩充【协议中从未声明过的方法】static 类方式也可以
  • 类的实例调用的时候也是调用的扩展中的实现

泛型

扩展中依然可以使用原类型中的泛型类型

符合条件才扩展

extension Stack : Equatable where E : Equatable {
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值