Swift学习这二十二:扩展(extension)

扩展(extension)
扩展是向一个已有的类、结构体或枚举类型添加新的功能。在swift中扩展是没有名字的,
但在Objective-C中Category是有名字的,而且只能扩展类(类别)

如在Swift中扩展是这么写的:

[objc]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. extension String {  
  2.   func reverseString() -> String {  
  3.     // do something if necessary   
  4.   }  
  5. }  
  6.   
  7. 在Objective-C中,是这么写的:  
  8. @interface NSString (ReverseStringExtension)   
  9. - (NSString *)reverseString; // implementent in .m file  
  10. @end   

Swift中扩展可以:
(1)添加计算实例属性(computed property)和计算类属性
(2)定义实例方法和类方法
(3)提供新的构造器
(4)定义下标(subscript)
(5)定义和使用新的嵌套类型
(6)使一个遵守某个接口


扩展语法(Extension syntax)
声明扩展的关键字extension

[objc]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. extension SomteType {  
  2.  // add sth  
  3. }  
  4.   
  5. 可以扩展类型时让类型遵守协议:  
  6. extension SomteType : SomeProtocol, OtherProtocol {  
  7.   // do sth if necessary  
  8. }  

扩展类型,添加计算属性:
[objc]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. // 添加长度单位属性  
  2. extension Double {  
  3.   var km: Double {  
  4.     return selfself * 1_000.0    
  5.   }  
  6.     
  7.   var m: Double {  
  8.     return self  
  9.   }  
  10.       
  11.   var cm: Double {  
  12.     return self / 100.0  
  13.   }  
  14.     
  15.   var mm: Double {  
  16.     return self / 1_000.0  
  17.   }    
  18.     
  19.   var ft: Double {  
  20.     return self / 3.28084  
  21.   }  
  22. }  
  23.   
  24. let oneInch = 25.4.mm  
  25. println("One inch is \(oneInch) meters"// prints One inch is 0.0254 meters  
  26.   
  27. let threeFeet = 3.ft  
  28. println("Three feet is \(threeFeet) meters"// prints Three feet is 0.914399970739201 meters  
  29.   
  30. let sum = 10.4.km + 122.5.km // 这么写法是不是很方便就能进行转换?Yes  
注意:
扩展可以添加新的计算属性,但不能添加存储属性,也不能向已有属性添加属性观察。


给值类型扩展新的构造器。
如果使用扩展给值类型添加一个构造器,如果该类型所有属性已经有默认值,但没有定制任何构造器,
此时我们可以调用默认的构造器和成员逐一构造器。
[objc]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. struct Size {  
  2.   var width = 0.0  
  3.   var height = 0.0  
  4. }  
  5.   
  6. struct Point {  
  7.   var x = 0.0  
  8.   var y = 0.0  
  9. }  
  10.   
  11. struct Rect {  
  12.   var origin = Point()  
  13.   var size = Size()  
  14. }  
  15.   
  16. // 这里因为Rect结构体都提供了属性的默认值,它可以自动会有一个默认的构造器和一个成员逐一的构造器,  
  17. // 即:init()方法和init(origin:Point, size: Size)  
  18. // 那么我们可以直接使用:  
  19. let defaultRect = Rect() // 调用默认构造器  
  20. let memberwiseRect = Rect(origin: Point(x: 2.0, y2.0), size: Size(width: 5.0, height5.0))  
  21.   
  22. // 下面我们给Rect扩展一个构造器  
  23. extension Rect {  
  24.   init(center: Point, size: Size) {  
  25.      let originX = center.x - size.width / 2.0  
  26.      let originY = center.y - size.height / 2.0  
  27.        
  28.      // 调用本类自动得到的成员逐一构造器  
  29.      self.init(origin: Point(x: originX, y: originY), size: size)  
  30.   }  
  31. }  

扩展方法:类方法(引用类型)、静态方法(值类型)和实例方法、修改实例方法

[objc]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. extension Int {  
  2.   // 参数是一个单类型的闭包,没有参数,没有返回值的闭包  
  3.   func repetions(task: () -> ()) {  
  4.     for i in 0..self {  
  5.       task()  
  6.     }  
  7.   }  
  8.   // 仅是例子,这是不好的设计  
  9.   static func multiply(a: Int, b: Int) -> Int {  
  10.     return a * b  
  11.   }    
  12.     
  13.   // 要修改Self,就需要是可改类型方法,需要加上关键字mutating  
  14.   mutating func square() {  
  15.     self = selfself * self  
  16.   }  
  17. }  
  18.   
  19. let number = 4  
  20. number.repetions { // 使用了trailing closure  
  21.   println("test extension")  
  22. }  
  23. // test extension  
  24. // test extension  
  25. // test extension  
  26. // test extension  
  27.   
  28. println(Int.multiply(23)) // prints 6  
  29. println(3.square()) // prints 9  


下标(subscripts)
扩展可以向一个已有类型添加新下标。如下:

[objc]  view plain  copy
 print ? 在CODE上查看代码片 派生到我的代码片
  1. extension Int {  
  2. // 下标[n]会返回十进制数字从右向左第n个数字  
  3.   subscript(index: Int) -> Int {  
  4.     var decimalBase = 1   
  5.     for _ in 1...index {  
  6.       decimalBase *= 10  
  7.     }  
  8.     return (self / decimalBase) % 10  
  9.   }  
  10. }  
  11.   
  12. println(746381295[0])  
  13. // returns 5  
  14. println(746381295[1])  
  15. // returns 9  
  16. println(746381295[2])  
  17. // returns 2  
  18. println(746381295[8])  
  19. // returns 7  



总结:个人认识扩展是很好用的功能,在项目中,会把通常的基础辅助方法扩展到已有类中,
这样可以方便整个工程的使用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值