// 扩展 就是为一个已有的 类, 结构体, 枚举, 或者 协议类型添加新功能, 这包括在没有权限获取 原始代码的情况下 扩展类型的能力 (即 逆向建模), 扩展和 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])

swift 学习- 23 -- 扩展的更多相关文章

  1. swift学习笔记之-扩展(Extensions)

    //扩展(Extensions) import UIKit /*扩展(Extensions):扩展 就是为一个已有的类.结构体.枚举类型或者协议类型添加新功能.这包括在没有权限获取原始源代码的情况下扩 ...

  2. Swift 学习笔记十五:扩展

    扩展就是向一个已有的类.结构体或枚举类型加入新功能(functionality).扩展和 Objective-C 中的分类(categories)相似.(只是与Objective-C不同的是,Swif ...

  3. Swift 学习笔记(扩展和泛型)

    在开始介绍Swift中的扩展之前,我们先来回忆一下OC中的扩展. 在OC中如果我们想对一个类进行功能的扩充,我们会怎么做呢. 对于面向对象编程的话,首先会想到继承,但是继承有两个问题. 第一个问题:继 ...

  4. Swift学习目录

    本学习基于苹果官方Swift学习材料,保留了原版90%左右的内容(一些项目开发中基本不用的知识点没有整理),并根据理解进行整理.如对原版感兴趣,可以直接单击链接阅读和学习. 第一部分 基础篇 1.基本 ...

  5. iOS ---Swift学习与复习

    swift中文网 http://www.swiftv.cn http://swifter.tips/ http://objccn.io/ http://www.swiftmi.com/code4swi ...

  6. 12套swift学习资源分享

    虽然objective-c编程语言在过去很长一段时间都是iOS应用开发的基础语言,且很多iOS开发者对其也深爱有佳,但是随着swift编程语言的问世,迅速发展为开发者追捧的语言.且今年伴随着swift ...

  7. Swift学习与复习

    swift中文网 http://www.swiftv.cn http://swifter.tips/ http://objccn.io/ http://www.swiftmi.com/code4swi ...

  8. 【swift学习笔记】二.页面转跳数据回传

    上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...

  9. 今天开始Swift学习

    今天开始Swift学习  在此记录笔记  以备之后查阅! allenhuang

随机推荐

  1. hashMap源码解析(四)

    ---恢复内容开始--- 在上文中讲到了putval这个方法,这里继续: final V putVal(int hash, K key, V value, boolean onlyIfAbsent, ...

  2. Django的csrf中间件

    csrf中间件 ​ csrf 跨站请求伪造 ​ 补充两个装饰器: ​ from django.views.decorators.csrf import csrf_exempt,csrf_protect ...

  3. NPOI2.2.0.0实例详解(九)—设置EXCEL单元格【时间格式】

    原文:http://blog.csdn.net/xxs77ch/article/details/50245391 using System; using System.Collections.Gene ...

  4. zabbix系列 ~ 如何更好的利用mysql监控

    一 简介:今天来聊聊一些关于mysql 监控需要关注的问题二 实现的原理   1 global status   2 variables 三 我们需要关注的zabbix性能图  1 事务类型      ...

  5. Ajax 及里面的XStream《黑马程序员_超全面的JavaWeb视频教程vedio》

    1. ajax是什么? * asynchronous javascript and xml:异步的js和xml * 它能使用js访问服务器,而且是异步访问! * 服务器给客户端的响应一般是整个页面,一 ...

  6. 【转载】NeurIPS 2018 | 腾讯AI Lab详解3大热点:模型压缩、机器学习及最优化算法

    原文:NeurIPS 2018 | 腾讯AI Lab详解3大热点:模型压缩.机器学习及最优化算法 导读 AI领域顶会NeurIPS正在加拿大蒙特利尔举办.本文针对实验室关注的几个研究热点,模型压缩.自 ...

  7. Workbook导出excel封装的工具类

    在实际中导出excel非常常见,于是自己封装了一个导出数据到excel的工具类,先附上代码,最后会写出实例和解释.支持03和07两个版本的 excel. HSSF导出的是xls的excel,XSSF导 ...

  8. 新年第一个目标一张表盘串讲所有canves的知识点

    我们的目标 首先是canves的坐标系统,基于浏览器的左上角为原点,x,y轴为正方向的坐标系统. 首先初始化,打标签 <canvas id="canvas" height=& ...

  9. Java基础1-Java概述;jdk安装配置

    计算机基本概念 windows : desktop系统. linux : 稳定性 + 安全性. centos . ubuntu.redhat.suse mac : 路径: 精准定位 目录: 所在的文件 ...

  10. Deep Learning Tutorial - Convolutional Neural Networks(LENET)

    CNN很多概述和要点在CS231n.Neural Networks and Deep Learning中有详细阐述,这里补充Deep Learning Tutorial中的内容.本节前提是前两节的内容 ...