The Swift Programming Language学习笔记(二十二)——扩展
来源:互联网 发布:玩暗黑3卡顿优化 编辑:程序博客网 时间:2024/06/16 03:51
- 扩展
- 扩展语法
- 计算型属性
- 构造器
- 方法
- 可变实例方法
- 下标
- 嵌套类型
扩展
扩展
就是为一个已有的类、结构体、枚举类型或者协议类型添加新功能。这包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模
)。扩展和Objective-C中的分类
类似。(与Objective-C不同的是,Swift的扩展没有名字。)
Swift 中的扩展可以:
- 添加计算型属性和计算型类型属性
- 定义实例方法和类型方法
- 提供新的构造器
- 定义下标
- 定义和使用新的嵌套类型
- 使一个已有类型符合某个协议
在Swift中,你甚至可以对协议进行扩展,提供协议要求的实现,或者添加额外的功能,从而可以让符合协议的类型拥有这些功能。
注意,扩展可以为一个类型添加新的功能,但是不能重写已有的功能。
扩展语法
使用关键字extension来声明扩展。可以通过扩展来扩展一个已有类型,使其采纳一个或多个协议。在这种情况下,无论是类还是结构体,协议名字的书写方式完全一样。
如果你通过扩展为一个已有类型添加新功能,那么新功能对该类型的所有已有实例都是可用的,即使它们是在这个扩展定义之前创建的。
计算型属性
扩展可以为已有类型添加计算型实例属性和计算型类型属性。
扩展可以添加新的计算型属性,但是不可以添加存储型属性,也不可以为已有属性添加属性观察器。
extension Double { var km: Double { return self * 1000 } // 计算型属性必须是var,即使是常量 var m : Double { return self } var cm: Double { return self / 100.0 } var mm: Double { return self / 1000.0 } var ft: Double { return self / 3.28084 } // 一米有3.28024英尺}let a = 1.0.cmprint(a) // 0.01let b = 1.km // 1看成是Double型print(b) // 1000.0let aMarathon = 42.km + 195.mprint(aMarathon) // 42195.0
构造器
扩展可以为已有类型添加新的构造器。这可以让你扩展其它类型,将你自己的定制类型作为其构造器参数,或者提供该类型的原始实现中未提供的额外初始化选项。
扩展能为类添加新的便利构造器,但是它们不能为类添加新的指定构造器或析构器。指定构造器和析构器必须总是由原始的类实现来提供。
注意,如果你使用扩展为一个值类型添加构造器,且该值类型的原始实现中未定义任何定制的构造器时,你可以在扩展中的构造器里调用逐一成员构造器。如果该值类型为所有存储型属性提供了默认值,你还可以在扩展中的构造器里调用默认构造器。如果你把定制的构造器写在值类型的原始实现中,上述规则将不再适用。
如果你使用扩展提供了一个新的构造器,你依旧有责任确保构造过程能够让实例完全初始化。
struct Size { var width = 0.0, height = 0.0}struct Point { var x = 0.0, y = 0.0}/** * 因为结构体Rect未提供定制的构造器,因此它会获得一个逐一成员构造器。又因为它为所有存储型属性提供了默认值,它又会获得一个默认构造器。 */struct Rect { var origin = Point() var size = Size()}let r1 = Rect()print(r1) // Rect(origin: Point(x: 0.0, y: 0.0), size: Size(width: 0.0, height: 0.0))let r2 = Rect(origin: Point(x: 10, y: 10), size: Size(width: 800, height: 640))print(r2) // Rect(origin: Point(x: 10.0, y: 10.0), size: Size(width: 800.0, height: 640.0))extension Rect { init(center: Point, size: Size) { let x = center.x - size.width / 2 let y = center.y - size.height / 2 self.init(origin: Point(x: x, y: y), size: size) }}let r3 = Rect(center: Point(x: 20, y: 20), size: Size(width: 5, height: 4))print(r3) // Rect(origin: Point(x: 17.5, y: 18.0), size: Size(width: 5.0, height: 4.0))
方法
扩展可以为已有类型添加新的实例方法和类型方法。
extension Int { func repetitons(task: () -> Void) { for _ in 0..<self { task() } }}3.repetitons({ print("Hello")})// 可以使用尾随闭包让调用更加简洁5.repetitons { print("OK")}
可变实例方法
通过扩展添加的实例方法也可以修改该实例本身。结构体和枚举类型中修改self
或其属性的方法必须将该实例方法标注为mutating
,正如来自原始实现的可变方法一样。
extension Int { mutating func square() -> Int { return self * self }}var a = 3 // 必须使用变量调用!不能使用常量或者字面值量print(a.square())
下标
扩展可以为已有类型添加新下标。
extension Int { subscript(var index: Int) -> Int { var base = 1 while index > 0 { base *= 10 --index } return (self / base) % 10 }}print(1234567890[0]) // 0print(1234567890[2]) // 8print(1234567890[11]) // 0,如果该Int值没有足够的位数,即下标越界,那么上述下标实现会返回0,犹如在数字左边自动补0
嵌套类型
扩展可以为已有的类、结构体和枚举添加新的嵌套类型。
extension Int { enum Kind { case Negative, Zero, Positive } var kind: Kind { switch self { case 0: return .Zero case let x where x > 0: return .Positive //case let x where x < 0: // 貌似完备了,但是依然报错没有default default: return .Negative } }}func printIntegerKind(numbers: [Int]) { for number in numbers { switch number.kind { case .Negative: // 由于已知number.kind是Int.Kind类型,因此在switch语句中,Int.Kind中的所有成员值都可以使用简写形式,例如使用. Negative而不是Int.Kind.Negative print("-", terminator: "、") case .Zero: print("0", terminator: "、") case .Positive: print("+", terminator: "、") } } print("")}let numbers = [1, -23, 0, 12, 45, -23, 3, -234]printIntegerKind(numbers) // +、-、0、+、+、-、+、-、
- The Swift Programming Language学习笔记(二十二)——扩展
- The Swift Programming Language学习笔记(十二)——方法
- The Swift Programming Language学习笔记 (二)——基础部分
- The Swift Programming Language学习笔记(二十)——类型转换
- The Swift Programming Language学习笔记(二十一)——嵌套类型
- The Swift Programming Language学习笔记(二十三)——协议
- The Swift Programming Language学习笔记(二十四)——泛型
- The Swift Programming Language学习笔记(二十五)——访问控制
- The Swift Programming Language学习笔记(二十六)——高级运算符
- The Swift Programming Language学习笔记(一)——初见Swift
- The Swift Programming Language学习笔记(三)——基本运算符
- The Swift Programming Language学习笔记(四)——字符串和字符
- The Swift Programming Language学习笔记(六)——控制流
- The Swift Programming Language学习笔记(五)——集合类型
- The Swift Programming Language学习笔记(七)——函数
- The Swift Programming Language学习笔记(八)——闭包
- The Swift Programming Language学习笔记(九)——枚举
- The Swift Programming Language学习笔记(十)——类和结构体
- android studio引入一个module
- 存储过程加入动态sql
- Erlang 程序设计 学习笔记(一) 基本概念
- Android-PullToRefresh 快速滑动产生的大片留白问题
- iOS 宏(define)与常量(const)的正确使用
- The Swift Programming Language学习笔记(二十二)——扩展
- 原来在内存申请地址也是一个费时的过程
- 大型网站架构系列:消息队列(二)
- Stackoverflow JAVA TOP 100问题翻译征集令
- ubuntu(服务端)+windows(客户端)搭建iscsi
- PAT (Basic Level)1015. 德才论
- 静态注册广播接收器
- APP上架,发布,打包
- The Swift Programming Language学习笔记(二十三)——协议