Swift学习笔记(十六)拓展

拓展

扩展就是向一个已有的类、结构体或枚举类型添加新功能(functionality)。这包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模)。扩展和 Objective-C中的分类(categories)类似。(不过与Objective-C不同的是,Swift的扩展没有名字。

extension SomeType {
    // 加到SomeType的新功能写到这里
}
按以下方式添加的协议遵循者( protocol conformance )被称之为在扩展中添加协议遵循者

extension SomeType: SomeProtocol, AnotherProctocol {
    // 协议实现写到这里
}
计算型属性

扩展可以向已有类型添加计算型实例属性和计算型类型属性。

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
    }
}<pre name="code" class="plain">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()
}
let defaultRect = Rect()
let memberwiseRect = Rect(origin: Point(x: 2.0, y: 2.0),
    size: Size(width: 5.0, height: 5.0))
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的原点是 (2.5, 2.5),大小是 (3.0, 3.0)

let oneInch = 25.4.mmprintln("One inch is \(oneInch) meters")// 打印输出:"One inch is 0.0254 meters"let threeFeet = 3.ftprintln("Three feet is \(threeFeet) meters")// 打印输出:"Three feet is 0.914399970739201 meters"let aMarathon = 42.km + 195.mprintln("A marathon is \(aMarathon) meters long")// 打印输出:"A marathon is 42495.0 meters long"

 

注意:扩展可以添加新的计算属性,但是不可以添加存储属性,也不可以向已有属性添加属性观测器(property observers)

构造器(Initializers)

扩展可以向已有类型添加新的构造器。这可以让你扩展其它类型,将你自己的定制类型作为构造器参数,或者提供该类型的原始实现中没有包含的额外初始化选项。

如果你使用扩展向一个值类型添加一个构造器,该构造器向所有的存储属性提供默认值,而且没有定义任何定制构造器(custom initializers),那么对于来自你的扩展构造器中的值类型,你可以调用默认构造器(default initializers)和成员级构造器(memberwise initializers) 正如在值类型的构造器授权中描述的,如果你已经把构造器写成值类型原始实现的一部分,上述规则不再适用。

如果你使用扩展提供了一个新的构造器,你依旧有责任保证构造过程能够让所有实例完全初始化

方法

扩展可以向已有类型添加新的实例方法和类型方法

extension Int {
    func repetitions(task: () -> ()) {
        for _ in 0..<self {
            task()
        }
    }
}

这个repetitions方法使用了一个() -> ()类型的单参数(single argument),表明函数没有参数而且没有返回值。

3.repetitions({
    println("Hello!")
})
// Hello!!!
// Hello!!!
// Hello!!!
使用 trailing 闭包使调用更加简洁

3.repetitions{
    println("Goodbye!")
}
// Goodbye!
// Goodbye!
// Goodbye!

通过拓展修改实例方法

通过扩展添加的实例方法也可以修改该实例本身。结构体和枚举类型中修改self或其属性的方法必须将该实例方法标注为mutating

extension Int {
    mutating func square() {
        self = self * self
    }
}
var someInt = 3
someInt.square()
//someInt此时的值为9

子脚本

扩展可以向一个已有类型添加新下标

extension Int {
    subscript(var digitIndex: Int) -> Int {
        var decimalBase = 1
        while digitIndex > 0 {
            decimalBase *= 10
            --digitIndex
        }
        return (self / decimalBase) % 10
    }
}
746381295[0]
// returns 5
746381295[1]
// returns 9
746381295[2]
// returns 2
746381295[8]
// returns 7

如果该Int值没有足够的位数,即下标越界,那么上述实现的下标会返回0,因为它会在数字左边自动补0

//746381295[9]  returns 0, 即等同于:0746381295[9]

嵌套类型

扩展可以向已有的类、结构体和枚举添加新的嵌套类型

Int中添加了嵌套枚举

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
        default:
            return .Negative
        }
    }
}
func printIntegerKinds(numbers: [Int]) {
    for number in numbers {
        switch number.kind {
        case .Negative:
            print("- ")
        case .Zero:
            print("0 ")
        case .Positive:
            print("+ ")
        }
    }
    print("\n")
}
printIntegerKinds([3, 19, -27, 0, -6, 0, 7])
// prints "+ + - 0 - 0 +"

注意number.kind是已知的Int.kind类型,正因为如此,所有的Int.kind成员值可以用简写形式在switch语句中.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值