扩展: 就是给一个现存类, 结构体, 枚举或者协议添加新的属性和方法的语法, 无需目标源码, 就可以把想要的代码加到目标上面。
但有一些限制条件需要说明:
1.不能添加一个已经存在的方法或者属性;
2.添加的属性不能是存储属性, 只能是计算属性;
格式:
extension 某个先有类型{
//增加新的功能
}
扩展计算属性
class Transport {
var scope:String
init(scope:String) {
self.scope = scope
}
}
extension Transport {
var extProperty:String{
get{
return scope
}
}
}
var myTrans = Transport(scope: "飞机")
print(myTrans.extProperty)
注意
: 扩展可以添加新的计算属性,但它们不能添加存储属性,或向现有属性添加属性观察者。
扩展构造器
- 扩展可以向类添加新的便利构造器,但是它们不能向类添加新的指定构造器或析构器。指定构造器或析构器必须始终由原始类实现提供。
- 如果使用扩展将构造器添加到值类型中,该值类型为其所有存储属性提供默认值,并且没有任何自定义构造器,则可以在扩展的构造器中调用该值类型的默认构造器和全能构造器。
- 如果使用扩展将构造器添加到声明在另一个模块中的结构体中,则
新的构造器只有从定义的模块中调用了构造器才能访问self
struct Size {
var width = 0.0, height = 0.0
}
struct Point {
var x = 0.0, y = 0.0
}
struct Rect {
var origin = Point()
var size = Size()
}
Rect结构为其所有属性提供默认值,所以它会自动接收默认构造器和全能构造器。这些构造器可用于创建新的Rect实例:
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)
let originY = center.y - (size.height / 2)
self.init(origin: Point(x: originX, y: originY), size: size)
}
}
let centerRect = Rect(center: Point(x: 4.0, y: 4.0), size: Size(width: 3.0, height: 3.0))
// centerRect's origin is (2.5, 2.5) and its size is (3.0, 3.0)
注意
:如果使用扩展来提供一个新初始化器,要确保构造器完成之后,每个实例都被完全初始化。
扩展方法
- 通过扩展增加的实例方法可以修改实例本身
如果结构体和枚举的方法要修改self或其属性,则需要使用mutating关键字标明
extension Int {
mutating func square() {
self = self * self
}
}
var someInt = 3
someInt.square()
扩展下标
- 扩展可以向已存在的类型添加下标
extension Int {
subscript(digitIndex: Int) -> Int {
var decimalBase = 1
for _ in 0..<digitIndex {
decimalBase *= 10
}
return (self / decimalBase) % 10
}
}
746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7
网友评论