Swift 5.1 (19) - 扩展

级别: ★☆☆☆☆
标签:「iOS」「Swift 5.1 」「扩展」
做者: 沐灵洛
审校: QiShare团队
php


扩展:在不须要访问源码的状况下,为现有的类,结构,枚举或协议类型添加了新功能。和Objective-C的分类很相似,不一样的是Swift的扩展没有名称。 Swift的扩展具有的能力:git

  • 添加实例计算属性和类计算属性
  • 定义实例方法和类方法
  • 提供新的初始化方法
  • 定义下标
  • 定义和使用新的嵌套类型
  • 使现有类型遵照某个协议

注意:扩展能够给一个类型添加新的功能,可是不能覆盖现有功能。github

Extension语法

声明扩展须要使用Extension关键字:编程

extension SomeType {
    // 可添加扩展的功能
}
复制代码

扩展能够扩展示有类型以使其采用一个或多个协议。swift

extension SomeType: SomeProtocol, AnotherProtocol {
    // 可添加协议要求的实现
}
复制代码

注意:若是定义扩展为现有类型添加新的功能,则此新功能在全部该类型已存在的实例上都是可用的,即便实例在定义扩展以前被建立。bash

计算属性

扩展能够添加实例计算属性和类计算属性。下例向Swift的内置Double类型添加了五个计算实例属性做为距离单位:微信

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("一英寸是 \(oneInch) 米")
// Prints "一英寸是 0.0254 米"
let threeFeet = 3.ft
print("三英尺是 \(threeFeet) 米")
// Prints "三英尺是 0.914399970739201 米"
let aMarathon = 42.km + 195.m
print("马拉松长 \(aMarathon) 米")
// Prints "马拉松长 42195.0 米"
复制代码

注意:扩展能够添加新的计算属性,可是不能添加存储属性,也不能为现有属性添加属性观察者。源码分析

初始化方法

扩展能够为现有类型添加初始化方法。post

扩展也能够为一个Class类型添加新的便利初始化方法,可是不能为一个Class类型添加新的指定初始化方法或反初始化方法。指定初始化方法或反初始化方法必须由原始的类实现。ui

若是使用扩展为值类型添加一个初始化方法,该值类型为其全部存储属性提供了默认值,而且没有自定义的初始化方法,则咱们能够在该值类型扩展中的初始化方法里调用默认的初始化方法或调用按成员生成的初始化方法。若值类型原始实现时,提供了自定义的初始化方法,则在该值类型扩展中的初始化方法里调用其自定义的初始化方法。 注:若想自定义的值类型既能调用默认初始化又能调用成员初始化还要能调用自定义的初始化,则这个自定义的初始化方法必须写在extension中。

若是使用扩展为声明在其余模块的结构体添加初始化方法,则新的初始化方法不能访问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()
    init(origi:Point,siz:Size) {
        origin = origi
        size = siz
    }
}
extension Rect {
    init(center:Point,size:Size) {
        let originX = center.x - (size.width / 2)
        let originY = center.y - (size.height / 2)
        self.init(origi: Point(x: originX, y: originY), siz: size)
        //! `Rect`原始定义中未自定义初始化方法则此处应该使用默认初始化方法或者成员初始化方法:`self.init(origin: Point(x: originX, y: originY), size: size)`
    }
}
复制代码

方法

扩展为现有类型添加实例方法和类方法。

extension Int {
    func repetitions(task: () -> Void) {
        for _ in 0..<self {
            task()
        }
    }
}
//调用 输出三次`Hello!`
3.repetitions {
    print("Hello!")
}
复制代码

可变的实例方法

值类型扩展中能够添加使用mutating修饰的实例方法,容许修改实例自己。

extension Int {
    mutating func square() {
        self = self * self
    }
}
var someInt = 3
someInt.square() // someInt : 9
复制代码

下标

扩展能够为现有类型添加新的下标。

//倒序输出一个整型数
extension Int {
    subscript(digitIndex:Int)->Int {
        var baseNum = 1
        for _ in 0..<digitIndex {
            baseNum *= 10
        }
        assert(baseNum <= self, "整数的索引越界了")
        return (self/baseNum)%10
    }
}
print(123456[5]) // 1
复制代码

嵌套类型

扩展可为现有类,结构体,枚举添加新的嵌套类型。

extension Int {
    
    enum Status : String,CaseIterable {
        case NoAuth = "NoAuth"
        case RequestError = "RequestError"
        case None = "None"
    }
    var netStatus : String {
        switch self {
        case 401:
            return Status.NoAuth.rawValue
        case let x where x >= 500 :
            return Status.RequestError.rawValue
        default:
            return Status.None.rawValue
        }
    }    
}
print(401.netStatus) //!< NoAuth
print(500.netStatus) //!< RequestError
print(402.netStatus) //!< None
复制代码

参考资料: swift 5.1官方编程指南


了解更多iOS及相关新技术,请关注咱们的公众号:

image

关注咱们的途径有:
QiShare(简书)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公众号)

推荐文章:
Swift 5.1 (18) - 嵌套类型 Swift 5.1 (17) - 类型转换与模式匹配 浅谈编译过程
深刻理解HTTPS 浅谈 GPU 及 “App渲染流程”
iOS 查看及导出项目运行日志
Flutter Platform Channel 使用与源码分析
开发没切图怎么办?矢量图标(iconFont)上手指南
DarkMode、WKWebView、苹果登陆是否必须适配?
奇舞团安卓团队——aTaller
奇舞周刊