跳转至

扩展

扩展

目录


扩展就是向一个已有的类、结构体或枚举类型添加新功能。这包括在没有权限获取原始源代码的情况下扩展类型的能力(逆向建模)。

Swift中的扩展可以:

  • 添加计算型属性和计算静态属性
  • 定义实例方法和类方法
  • 提供新的构造器
  • 定义下包
  • 定义和使用新的嵌套类型
  • 使用一个已有的类型符合某个协议

声明扩展使用关键字extension

1
2
3
extension SomeType {

}

1.添加计算型属性

扩展可以添加新的计算属性,但是不可以添加新的存储属性,也不可以向已有属性添加属性观察器。

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_00.0
    }
    var ft:Double{
        return self/3.28084
    }
}

let oneInch = 25.4.mm

println("One inch is \(oneInch) meters")
// 输出 One inch is 0.254 meters

let threeFeet = 3.ft

println("Three feet is \(threeFeet) meters")
// 输出 Three feet is 0.914399970739201 meters

2.添加构造器

扩展能向类中添加新的便利构造器,但是它们不能向类中添加新的指定构造器或析构函数。

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))

3.添加和修改方法

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

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

3.repetitions({println("Hello!")})

//Hello!
//Hello!
//Hello!

// 尾随闭包

3.repetitions{println("Hello!")}
通过扩展添加的实例方法也可以修改该实例本身。结构体和枚举类型中修改self或其他属性的方法必须将该实例方法标注为mutating。

// 修改Int的square方法
extension Int{
    mutating func square(){
        self = self * self
    }
}

var someInt = 3

someInt.square()

4.添加下标

// 添加一个整形下标该下标[n]返回十进制数字从右向左数的第n个数字
//123456789[0]返回9
//123456789[1]返回8
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

5.添加嵌套类型

// 判断字符是元音 辅音 还是其他类型
extension Character {
    enum Kind {
        case Vowel, Consonant, Other
    }
    var kind: Kind {
        switch String(self).lowercaseString {
        case "a", "e", "i", "o", "u":
            return .Vowel
        case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
        "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
            return .Consonant
        default:
            return .Other
        }
    }
}

func printLetterKinds(word: String) {
    println("'\(word)' is made up of the following kinds of letters:")
    for character in word {
        switch character.kind {
        case .Vowel:
            print("vowel ")
        case .Consonant:
            print("consonant ")
        case .Other:
            print("other ")
        }
    }
    print("\n")
}
printLetterKinds("Hello")
// 'Hello' is made up of the following kinds of letters:
// consonant vowel consonant consonant vowel

评论