目录
扩展(Extension)
1、Swift中的扩展,有点类似于OC中的分类(Category)
2、扩展可以为枚举、结构体、类、协议添加新功能
可以添加方法、计算属性、下标、(便捷)初始化器、嵌套类型、协议等等
3、扩展不能办到的事情
不能覆盖原有的功能
不能添加存储属性,不能向已有的属性添加属性观察器
不能添加父类
不能添加指定初始化器,不能添加反初始化器
。。。。
extension Double { var km: Double { self * 1_000.0 } var m: Double { self } var dm: Double { self / 100.0 } var cm: Double { self / 10.0 } var mm: Double { self / 1_000.0 } } var d = 100.0 d.km d.m d.dm
var arr: Array<Int> = [10, 20, 30] extension Array { subscript(nullable idx: Int) -> Element? { if (startIndex ..< endIndex).contains(idx) { return self[idx] } return nil } } print(arr[nullable: 1] ?? 0)
extension Int { func repeats(task: () -> Void) { for _ in 0..<self { task() } } 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 } }
协议与初始化器
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 && left.name == right.name } convenience init() { self.init(age: 0, name: "") } }
1、如果希望自定义初始化器的同时,编译器也能够生成默认初始化器,那么可以在扩展中编写自定义初始化器
struct Point { var x: Int = 0 var y: Int = 0 } extension Point { init(_ point: Point) { self.init(x: point.x, y: point.y) } }
2、required初始化器不能写在扩展中
协议
1、如果一个类型已经实现了协议的所有要求,但是还没有声明它遵守了这个协议
可以通过扩展来让它遵守这个协议
2、给协议进行扩展后,凡是遵守了这个协议的都会有对应的扩展方法,以下面为例,编写一个函数,判断一个证书是否为奇数。
extension BinaryInteger { func isOdd() -> Bool { self % 2 != 0 } }
3、扩展可以给协议提供默认实现,也间接实现 可选协议 的效果
protocol TestProtocol { func test1() } extension TestProtocol { func test1() { print("TestProtocol test1") } func test2() { print("TestProtocol test2") } } class TestClass: TestProtocol { func test1() { print("TestClass test1") } func test2() { print("TestClass test2") } } var cls: TestProtocol = TestClass() cls.test1() //TestClass test1 cls.test2() //TestProtocol test2
泛型
1、扩展中依然可以使用原类型中的泛型类型
2、符合条件才扩展
extension Stack: Equatable where E: Equatable { }