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

    题目:实现数码管动态扫描功能,将十六个开关的值以十六进制的方式在4个数码管上同时显示出来. `timescale 1ns / 1ps module top( clk, sw, seg, an ); / ...

  2. XXE攻防技术

    http://bobao.360.cn/learning/detail/3841.html http://www.freebuf.com/articles/web/97833.html http:// ...

  3. [C++]环状序列(CircularSequence,ACM/ICPC Seoul 2004,UVa1584)

    Question 例题3-5 环状序列(CircularSequence,ACM/ICPC Seoul 2004,UVa1584) 长度为n的环状串有n种表示方法,分别为从某个位置开始顺时针得到,在这 ...

  4. 关于“ubuntu18.04下网易云无法启动”的问题解决方案

    1. 最简单的解决方案(参考文章:亢奋猫): 更正:在更改启动文件netease-cloud-music.desktop时应为:将第11行处的“Exec=netease-cloud-music %U” ...

  5. webpack学习笔记——打包js

    1.新建一个入口js文件,如entry.js,代码如下: document.write("It works.") 2.然后编译 entry.js 并打包到 bundle.js(会自 ...

  6. 「LibreOJ Round #6」花火

    转化思维的好题! 链接:here 大致题意: 有$ n$个数字,你每次可以交换相邻两个,还有一次交换任意两个元素的机会,求最少的交换次数使得这些数字升序排序(原数列两两不同) $ solotion:$ ...

  7. 添加,删除List<Map<String, Object>>元素

    这里讲对List<Map<String, Object>>的数据结构的添加和删除实例 添加 //初始化 List<Map<String, Object>> ...

  8. MySql cmd下的学习笔记 —— 有关表的操作(对表的增删改查)

    create table 表名 ( 列名1 列属性, 列名2 列属性 ... ... 列名n 列属性 )engine myisam charset utf8; (增加表的一列) (一)在表的最末列增加 ...

  9. Django中的csrf基础了解

    简介 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防跨站请求伪造功能有 ...

  10. CF1101G (Zero XOR Subset)-less

    题目地址:CF1101G (Zero XOR Subset)-less 线性基基础题 预处理一个前缀异或和 \(s_i\) 这样题目就变成了:在 \(n\) 个 \(s_i\) 中尽量选择多的数使选择 ...