Swift

扩展

本文详细介绍了 Swift 中的扩展,包括添加计算属性、定义方法、提供新的初始化器、定义下标、定义嵌套类型以及使已有类型遵循协议。

扩展(Extensions)为现有的类、结构体、枚举类型或协议类型添加新功能。这包括在没有权限获取原始源代码的情况下扩展类型的能力(即“逆向建模”)。

扩展的语法

使用 extension 关键字声明扩展:

extension SomeType {
    // 为 SomeType 添加的新功能写到这里
}

计算属性 (Computed Properties)

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

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
print("One inch is \(oneInch) meters")
// 打印 "One inch is 0.0254 meters"

初始化器 (Initializers)

扩展可以为已有类型添加新的初始化器。这允许你扩展其他类型以接受你自己的自定义类型作为初始化参数,或者提供该类型的原始实现中未包含的额外初始化选项。

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

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

方法 (Methods)

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

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

3.repetitions {
    print("Hello!")
}
// 打印 "Hello!" 三次

下标 (Subscripts)

扩展可以为已有类型添加新下标。

extension Int {
    subscript(digitIndex: Int) -> Int {
        var decimalBase = 1
        for _ in 0..<digitIndex {
            decimalBase *= 10
        }
        return (self / decimalBase) % 10
    }
}

嵌套类型 (Nested Types)

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

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

遵循协议 (Protocol Conformance)

扩展可以用于使已有的类型遵循一个或多个协议。

extension Rect: Equatable {
    static func == (lhs: Rect, rhs: Rect) -> Bool {
        return lhs.size == rhs.size && lhs.origin == rhs.origin
    }
}
在 GitHub 上编辑

上次更新于