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

    非常好的dp,锻炼思维 f[i][j][k] 前i行有j列放1,k列放2 #include<bits/stdc++.h> #define int long long #define rep ...

  2. Flink 学习(一)

    摘自Flink官网https://flink.apache.org/ 最近看到公司有Flink平台,正好做过storm和spark streaming上的业务,借着这个机会把flink也学了.正好比较 ...

  3. Linux或UNIX系统配置检查

    1. Linux或UNIX系统配置检查 系统配置的扫描是基于被动式策略进行扫描,主要检测主机上是否存在配置错误或者不符合预定义的安全策略的配置,通常需要管理员权限才能执行的扫描. 在Linux或UNI ...

  4. RHEL 6.4 通过mysql安装文件安装mysql

    参考文章:http://www.linuxidc.com/Linux/2013-12/93507.htm 1.首先下载mysql安装文件 我是下载的最新版的5.6 2. 以RPM方式安装MySQL 在 ...

  5. react路由的安装及格式和使用方法

    react路由的安装: 在要创建项目的目录命令窗里输入: cnpm install -g create-react-app create-react-app  项目名 在创建好的项目目录命令窗里输入: ...

  6. VS 中NuGet 尝试还原程序包时出错"*"已拥有为"**"定义的依赖项

    之前从Git检出项目以后,项目编译不能通过,发现是缺少依赖的外部插件,于是通过NuGet去获取项目依赖的插件,如何通过NuGet恢复使用的插件请使用NuGet还原项目插件. 但是就是在使用NuGet还 ...

  7. python - one day

    1. python历史. 2008 年出现 python 2.7 与 python 3.0 两个版本,后来 吉多·范罗苏姆 大叔决定停用 python 2.7,但因用户反对,于是决定于 2020 年停 ...

  8. JDBC、DBCP、C3P0、jdbc-pool--链接方式?连接池?

    连接方式: java连接数据库的四种方式 - Cece_2012的专栏 - CSDN博客http://blog.csdn.net/cece_2012/article/details/7485482 J ...

  9. 动态规划 - 198. House Robber

    URL : https://leetcode.com/problems/house-robber/ You are a professional robber planning to rob hous ...

  10. [BugBounty] Sleeping stored Google XSS Awakens a $5000 Bounty

    来源:https://blog.it-securityguard.com/bugbounty-sleeping-stored-google-xss-awakens-a-5000-bounty/ 理解 ...