swift 学习- 23 -- 扩展
// 扩展 就是为一个已有的 类, 结构体, 枚举, 或者 协议类型添加新功能, 这包括在没有权限获取 原始代码的情况下 扩展类型的能力 (即 逆向建模), 扩展和 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 -- 扩展的更多相关文章
- swift学习笔记之-扩展(Extensions)
//扩展(Extensions) import UIKit /*扩展(Extensions):扩展 就是为一个已有的类.结构体.枚举类型或者协议类型添加新功能.这包括在没有权限获取原始源代码的情况下扩 ...
- Swift 学习笔记十五:扩展
扩展就是向一个已有的类.结构体或枚举类型加入新功能(functionality).扩展和 Objective-C 中的分类(categories)相似.(只是与Objective-C不同的是,Swif ...
- Swift 学习笔记(扩展和泛型)
在开始介绍Swift中的扩展之前,我们先来回忆一下OC中的扩展. 在OC中如果我们想对一个类进行功能的扩充,我们会怎么做呢. 对于面向对象编程的话,首先会想到继承,但是继承有两个问题. 第一个问题:继 ...
- Swift学习目录
本学习基于苹果官方Swift学习材料,保留了原版90%左右的内容(一些项目开发中基本不用的知识点没有整理),并根据理解进行整理.如对原版感兴趣,可以直接单击链接阅读和学习. 第一部分 基础篇 1.基本 ...
- iOS ---Swift学习与复习
swift中文网 http://www.swiftv.cn http://swifter.tips/ http://objccn.io/ http://www.swiftmi.com/code4swi ...
- 12套swift学习资源分享
虽然objective-c编程语言在过去很长一段时间都是iOS应用开发的基础语言,且很多iOS开发者对其也深爱有佳,但是随着swift编程语言的问世,迅速发展为开发者追捧的语言.且今年伴随着swift ...
- Swift学习与复习
swift中文网 http://www.swiftv.cn http://swifter.tips/ http://objccn.io/ http://www.swiftmi.com/code4swi ...
- 【swift学习笔记】二.页面转跳数据回传
上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...
- 今天开始Swift学习
今天开始Swift学习 在此记录笔记 以备之后查阅! allenhuang
随机推荐
- 【bzoj 3524】[Poi2014]Couriers
Description 给一个长度为n的序列a.1≤a[i]≤n.m组询问,每次询问一个区间[l,r],是否存在一个数在[l,r]中出现的次数大于(r-l+1)/2.如果存在,输出这个数,否则输出0. ...
- 【BZOJ】2286: [Sdoi2011]消耗战 虚树+DP
[题意]给定n个点的带边权树,每次询问给定ki个特殊点,求隔离点1和特殊点的最小代价.n<=250000,Σki<=500000. [算法]虚树+DP [题解]考虑普通树上的dp,设f[x ...
- js获取网页面的高度和宽度
网页可见区域宽:document.body.clientWidth网页可见区域高:document.body.clientHeight网页可见区域宽:document.body.offsetWidth ...
- python中矩阵的用法
python矩阵的表示真是让人头大,下面记录一下具体用法:array是numpy库里的.不管怎样, 一.首先导入 numpy: 1)import numpy 2)from numpy import * ...
- DAO层设计
一.类图分析 二.参考文档 ( JavaBean中DAO设计模式介绍)(附:设计源码) 三.类图设计文件 百度云盘:https://pan.baidu.com/s/1i5xaS8P[Power Des ...
- Swiper.js使用教程
官网地址:(http://www.swiper.com.cn/). 一.Swiper.js简介: Swiper(前称Swiper master) 是一款免费以及轻量级的移动设备触控滑块的js框架,使用 ...
- 牛客寒假算法基础集训营4 F(二分+拓扑判环)
题目链接 题目的输出:对于每次提问,输出一行"Yes"表示大家都遵守了群规,反之输出"No". 那么输出的就是一连串的yes和no了,二分一下无环的最大提问位置 ...
- 谈谈jQuery中的数据类型检测
这次是分享jQuery代码中的一些简写技巧,分析jQuery是如何优化代码的,如何用最少的代码来实现jQuery. 在我们工作中也常常会遇到一些数据类型检测,一些方法调用的形式 1 var arr = ...
- keepalived高可用系列~ keepalived+proxysql
一 简介:介绍下高可用通用的方案 二 目的:一个中间件提供服务,故障后,另一个中间件提供服务 三 手段: 应用keepalived的vrrp_scripts服务 四 具体配置 global_defs ...
- Javascript - ExtJs - TabPanel组件
示例 Ext.create('Ext.tab.Panel', { width: "100%", renderTo: "tabBox", ...