Swift - 扩展
2022-04-03 本文已影响0人
aven_kang
Swift中的扩展,有点类似OC中的Category
1.扩展可以为枚举、结构体、类、协议添加新功能
2.可以添加方法、计算属性、下标、便捷初始化器、嵌套类型、协议等
扩展不能办到的事
1.不能覆盖原有的功能
2.不能添加存储属性,不能向已有的属性添加属性观察器
3.不能添加父类
4.不能添加指定初始化器,不能添加反初始化器
示例
extension Array {
subscript(nullable idex: Index) -> Element? {
if (self.startIndex..<self.endIndex).contains(idex) {
return self[idex]
}
return nil
}
}
截屏2022-03-02 下午9.46.08.png
通过观察图片可以看出,这是对数组进行了一个扩展,用来防止越界而引发运行时奔溃,最终的打印结果是nil
extension Double {
var km:Double { return self*1000 }
var m:Double { self }
var dm: Double { self/10 }
var cm: Double { self/100 }
var mm: Double { self/1000 }
}
var kim = 10.0
print(kim.km) // 10000.0
print(kim.dm) // 1.0
print(kim.cm) // 0.1
extension Int {
func repetitons(task:()->Void) {
for _ in 0..<self {
task()
}
}
mutating func square() -> Int {
self = self * self
return self
}
enum Kind { case negative,zero,positive }
var kind : Kind {
switch self {
case 0:
return .zero
case let x where x > 0:
return .positive
default:
return .negative
}
}
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex { decimalBase *= 10 }
return (self/decimalBase) % 10
}
}
var count = 456
print(count.kind) // positive
print(count[1]) // 4
print(count[2]) // 5
print(count[3]) // 6
var subCount = 3
subCount.repetitons {
print("hahah") // 循环打印3次
}
结构体、协议、初始化器
struct subPoint {
var x : Int = 0
var y : Int = 0
}
extension subPoint {
init(_ point: subPoint){
self.init(x:point.x,y:point.y)
}
}
在上面的代码中,扩展了subPoint的初始化器,因为我们知道,一旦在subPoint内部指定了初始化器后,subPoint在初始化的时候,就不能再使用系统的方式去初始化了,比如如下代码
var p1 = Point()
var p2 = Point(x:10)
var p3 = Point(y:10)
var p4 = Point(x:10,y:20)
如何想保持结构体自身的初始化器,又能使用自己的定义的呢,答案就是使用拓展
class Person {
var age:Int
var name:String
init(age:Int,name:String) {
self.age = age
self.name = name
}
}
extension Person : Equatable {
static func == (left:Person, right:Person) -> Bool {
left.age == right.age
}
convenience init(){
self.init(age: 0, name: "jack")
}
}
可以为Person拓展协议,为Person类添加了比较两个类是否等价的功能,也定义了一个便捷初始化器
protocol TestProtocol {
func test()
}
class TestClass {
}
extension TestClass : TestProtocol {
func test() {
print("aahhah")
}
}
自定义了一个类,但是并为遵守协议,如何不在本类中实现协议,可以通过扩展,如上诉代码,就可以很好的做到协议(代理)与类之间的分离,本类中不会有过多的协议方法而显得臃肿
问题,编写一个函数,判断是否为奇数
extension BinaryInteger {
func idOdd() -> Bool { self % 2 != 0 }
}
BinaryInteger 这个关键字,代表了所有的整型,int,UInt等等
var integer = 10
integer.idOdd() // true