• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

swift学习-23--扩展

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

 

// 扩展 就是为一个已有的 类, 结构体, 枚举, 或者 协议类型添加新功能, 这包括在没有权限获取 原始代码的情况下 扩展类型的能力 (即 逆向建模), 扩展和 OC 中的分类类似, (与 OC 不同的是, Swift 的扩展没有名字)

 

// Swift 中的扩展可以

// 1: 添加计算型属性 和 计算型类型属性

// 2: 定义实例方法 和 类型方法

// 3: 提供新的构造器

// 4: 定义下标

// 5: 定义 和 使用新的嵌套结构

// 6: 使一个已有类型复合某个协议

 

// 在 Swift 中, 你甚至可以对协议进行扩展, 提供协议要求的实现, 或者添加额外的功能, 从而可以让符合协议的类型拥有这些功能.

 

// 扩展可以为一个类型添加新的功能, 但是不能重复已有的功能

 

 

 

 

 

// 扩展语法

// 使用 关键字 extension 来声明扩展:

 

// extension SomeType{

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

// }

 

// 可以通过扩展来扩展一个已有类型, 使其采纳一个或者多个协议, 在这种情况下, 无论是 类, 还是结构体, 协议名字的书写方式完全一样

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

    }

    

}

 

let oneInch = 25.4.mm

print("One inch is \(oneInch) meters")

 

let threeFeet = 3.ft

print("Three feet is \(threeFeet) meters")

 

 

// 这些计算型属性表达的含义是把一个 Double 值看做是某单位下的长度值, 即使它们被实现为计算型属性. 但这些属性的名字仍可紧接一个浮点型字面值, 从而通过点语法来使用, 并以此实现距离转换

 

// 这些属性是只读的计算型属性, 为了更简洁, 省略了 get 关键字, 它们的返回值是 Double, 并且可以用于所有接受 Double 值的数学计算中:

 

let aMarathon = 42.km + 195.m

print("A marathon is \(aMarathon) meters long")

 

// 注意 : 扩展可以添加 新的计算型属性, 但是不可以 添加存储型属性, 也不可以为已有属性添加属性观察器

 

 

 

 

 

// 构造器

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

 

// 扩展能为类型添加新的便利构造器, 但是他们不能为类添加新的指定构造器 或 析构器, 指定构造器 和 析构器必须总是由原始的类实现来提供

 

// 注意 : 如果你使用扩展为一个值类型添加构造器 , 同时该类型的原始实现中 未定义任何指定的构造器且 所有存储属性提供了默认值, 那么我们就可以在扩展中的构造器里调用默认构造器 和逐一成员构造器

 

struct Size{

    var width = 0.0

    var 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.init(origin: Point.init(x: 2.0, y: 2.0), size: Size.init(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.init(x: originX, y: originY), size: size)

    

    }

}

 

// 这个新的构造器首先根据提供的 center 和 size 的值计算一个合适的原点, 然后调用该结构体的逐一成员构造器 init(origin:size:) , 该构造器将新的原点和大小的值保存到了相应的属性中

 

let centerRect = Rect.init(center: Point.init(x: 4.0, y: 4.0), size: Size.init(width: 3.0, height: 3.0))

 

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

 

 

 

 

// 方法

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

 

extension Int{

    func repetitions(task: () -> Void) {

        for _ in 0..<self {

            task()

        }

    }

}

 

// 这个 repetitions(task:) 方法接受一个 () -> Void 类型的参数, 表示没有一个没有参数没有返回值的函数

 

// 定义该扩展之后, 你就可以对任意整数调用 repetitions(task:) 方法. 将闭包中的人物执行整数对应的次数

 

3.repetitions {

    print("hello!")

}

 

 

 

 

 

// 可变实例方法

// 通过扩展添加的实例方法也可以修改实例本身. 结构体 和 枚举类型中修改 self 或其 属性的方法必须将该实例方法标注 为 mutating, 正如来自原始实现的可变方法一样

 

extension Int{

    mutating func square(){

        self = self * self

    }

}

 

var someInt = 3

someInt.square()

print(someInt)

 

 

 

 

 

 

// 下标

// 扩展可以为 已有的类型添加新的下标, 

extension Int{

    subscript(digitIndex: Int) -> Int{

        var decimalBase = 1

        for _ in 0..<digitIndex {

            decimalBase *= 10

        }

        

        return (self / decimalBase) % 10

    }

}

 

print(746381295[0])

 

print(56416414551[6])

 

print(51465146541[5])

 

print(8454654564[3])

 

 

 

 

 

 

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

 

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

        }

    }

    

}

 

// 该例子为 Int 添加了嵌套类型, 这个名为 Kind 的枚举类型表示特定整数的类型, 具体来说, 就是表示整数是 正数,0 ,还是 负数

 

// 这个例子还为 Int 添加了一个计算型实例属性, 即 kind , 用来根据整数返回适当的 Kind 枚举成员

 

func printIntegerKinds(_ numbers: [Int]){

    for number in numbers {

        switch number.kind {

        case .Negative:

            print("-")

        case .Zero:

            print("0")

        case .Positive:

            print("+")

            

        }

    }

}

 

printIntegerKinds([21,-54,81,0,0,0,-84,95])


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Swift实战-小QQ(第3章):QQ主界面布局发布时间:2022-07-14
下一篇:
[Swift]LeetCode245.最短单词距离III$ShortestWordDistanceIII发布时间:2022-07-14
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap