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

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

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

extension String {
  func reverseString() -> String {
    // do something if necessary 
  }
}

在Objective-C中,是这么写的:
@interface NSString (ReverseStringExtension) 
- (NSString *)reverseString; // implementent in .m file
@end 

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


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

extension SomteType {
 // add sth
}

可以扩展类型时让类型遵守协议:
extension SomteType : SomeProtocol, OtherProtocol {
  // do sth if necessary
}

扩展类型,添加计算属性:
// 添加长度单位属性
extension Double {
  var km: Double {
    return self * 1_000.0  
  }
  
  var m: Double {
    return self
  }
	
  var cm: Double {
    return self / 100.0
  }
  
  var mm: Double {
    return self / 1_000.0
  }  
  
  var ft: Double {
    return self / 3.28084
  }
}

let oneInch = 25.4.mm
println("One inch is \(oneInch) meters") // prints One inch is 0.0254 meters

let threeFeet = 3.ft
println("Three feet is \(threeFeet) meters") // prints Three feet is 0.914399970739201 meters

let sum = 10.4.km + 122.5.km // 这么写法是不是很方便就能进行转换?Yes
注意:
扩展可以添加新的计算属性,但不能添加存储属性,也不能向已有属性添加属性观察。


给值类型扩展新的构造器。
如果使用扩展给值类型添加一个构造器,如果该类型所有属性已经有默认值,但没有定制任何构造器,
此时我们可以调用默认的构造器和成员逐一构造器。
struct Size {
  var width = 0.0
  var height = 0.0
}

struct Point {
  var x = 0.0
  var y = 0.0
}

struct Rect {
  var origin = Point()
  var size = Size()
}

// 这里因为Rect结构体都提供了属性的默认值,它可以自动会有一个默认的构造器和一个成员逐一的构造器,
// 即:init()方法和init(origin:Point, size: Size)
// 那么我们可以直接使用:
let defaultRect = Rect() // 调用默认构造器
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0), size: Size(width: 5.0, height: 5.0))

// 下面我们给Rect扩展一个构造器
extension Rect {
  init(center: Point, size: Size) {
     let originX = center.x - size.width / 2.0
	 let originY = center.y - size.height / 2.0
	 
	 // 调用本类自动得到的成员逐一构造器
	 self.init(origin: Point(x: originX, y: originY), size: size)
  }
}

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

extension Int {
  // 参数是一个单类型的闭包,没有参数,没有返回值的闭包
  func repetions(task: () -> ()) {
    for i in 0..self {
	  task()
	}
  }
  // 仅是例子,这是不好的设计
  static func multiply(a: Int, b: Int) -> Int {
    return a * b
  }  
  
  // 要修改Self,就需要是可改类型方法,需要加上关键字mutating
  mutating func square() {
    self = self * self
  }
}

let number = 4
number.repetions { // 使用了trailing closure
  println("test extension")
}
// test extension
// test extension
// test extension
// test extension

println(Int.multiply(2, 3)) // prints 6
println(3.square()) // prints 9


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

extension Int {
// 下标[n]会返回十进制数字从右向左第n个数字
  subscript(index: Int) -> Int {
    var decimalBase = 1 
	for _ in 1...index {
	  decimalBase *= 10
	}
	return (self / decimalBase) % 10
  }
}

println(746381295[0])
// returns 5
println(746381295[1])
// returns 9
println(746381295[2])
// returns 2
println(746381295[8])
// returns 7



总结:个人认识扩展是很好用的功能,在项目中,会把通常的基础辅助方法扩展到已有类中,
这样可以方便整个工程的使用。


  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值