学习Swift -- 拓展
拓展(Extension)
扩展就是向一个已有的类、结构体、枚举类型或者协议类型添加新功能。这包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模)。扩展和 Objective-C 中的分类(categories)类似。(不过与 Objective-C 不同的是,Swift 的扩展没有名字。)
Swift的拓展可以:
- 添加计算型属性和计算型静态属性
- 定义实例方法和类型方法
- 提供新的构造器
- 定义下标
- 定义和使用新的嵌套类型
- 使一个已有类型符合某个协议
注意:扩展可以对一个类型添加新的功能,但是不能重写已有的功能。
基本语法:
class SomeClass {
}
extension SomeClass {
// 在这里可以添加SomeClass的新功能
}
一个扩展可以扩展一个已有类型,使其能够适配一个或多个协议。当这种情况发生时,协议的名字应该完全按照类或结构体的名字的方式进行书写:
protocol SomeProtocol {
}
class SomeClass {
}
extension SomeClass : SomeProtocol {
}
计算型属性
扩展可以向已有类型添加计算型实例属性和计算型类型属性。
注意:扩展可以添加新的计算属性,但是不可以添加存储属性,也不可以向已有属性添加属性观测器。
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(oneInch)
// 0.0254
let threeFeet = 3.0.ft
print(threeFeet)
// 0.914399970739201
let aMarathon = 42.0.km + 195.0.m
print(aMarathon)
// 42195
构造器
扩展可以向已有类型添加新的构造器。这可以让你扩展其它类型,将你自己的定制类型作为构造器参数,或者提供该类型的原始实现中没有包含的额外初始化选项。
扩展能向类中添加新的便利构造器,但是它们不能向类中添加新的指定构造器或析构器。指定构造器和析构器必须总是由原始的类实现来提供。
注意:如果你使用扩展向一个值类型添加一个构造器,在该值类型已经向所有的存储属性提供默认值,而且没有定义任何定制构造器时,你可以在值类型的扩展构造器中调用默认构造器和逐一成员构造器。正如在值类型的构造器代理中描述的,如果你已经把构造器写成值类型原始实现的一部分,上述规则不再适用。
struct Size {
var width = 0.0, height = 0.0
}
struct Point {
var x = 0.0, y = 0.0
}
struct Rect {
// Rect结构体为所有属性提供了默认值,而且也没有自定义构造器,这样可以在拓展中调用Rect的逐一构造器和默认构造器
var origin = Point(), size = Size()
}
extension Rect {
// 在拓展中自定义了构造器
init(center: Point, size: Size) {
let x = center.x - size.width / 2
let y = center.y - size.height / 2
self.init(origin: Point(x: x, y: y), size: size)
}
}
let rect = Rect(center: Point(x: 50, y: 50), size: Size(width: 25, height: 30))
方法
扩展可以向已有类型添加新的实例方法和类型方法。
extension Int {
func repetitions(task: () -> ()) {
for _ in 0 ..< self {
task()
}
}
}
3.repetitions {
print("hello") // 打印3次 "hello"
}
修改实例方法
通过扩展添加的实例方法也可以修改该实例本身。结构体和枚举类型中修改self或其属性的方法必须将该实例方法标注为mutating,正如来自原始实现的修改方法一样。
extension Int {
// 定义了值类型修改实例的方法
mutating func square() {
self = self * self
}
}
var number = 3
number.square() // number 现在的值是 9
下标
扩展可以向一个已有类型添加新下标。
extension Int {
subscript (var index: Int) -> Int {
var decimalBase = 1
while index > 0 {
decimalBase *= 10
index -= 1
}
return self / decimalBase % 10
}
}
15699632[2] // return 6
15699632[3] // return 9
15699632[4] // return 9
15699632[5] // return 6
15699632[6] // return 5
嵌套类型
扩展可以向已有的类、结构体和枚举添加新的嵌套类型:
extension Int {
enum Kind {
case Negative, Zero, Positive
}
var kind: Kind {
switch self {
case 0:
return .Zero
case let number where number > 0 :
return .Positive
default:
return .Negative
}
}
}
func printIntegerKinds(numbers: [Int]) {
for number in numbers {
switch number.kind {
case .Negative:
print(" - ")
case .Zero:
print(" 0 ")
default:
print(" + ")
}
}
}
printIntegerKinds([0, 11, -4, 5, 0])
学习Swift -- 拓展的更多相关文章
- ios -- 教你如何轻松学习Swift语法(三) 完结篇
前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦. 一.自动引用计数 1.自动引用计数工作机制 1.1 swift和o ...
- ios -- 教你如何轻松学习Swift语法(二)
前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦. 一.可选类型(重点内容) 1.什么是可选类型? 1.1在OC开 ...
- ios -- 教你如何轻松学习Swift语法(一)
目前随着公司开发模式的变更,swift也显得越发重要,相对来说,swift语言更加简洁,严谨.但对于我来说,感觉swift细节的处理很繁琐,可能是还没适应的缘故吧.基本每写一句代码,都要对变量的数据类 ...
- 一步一步学习Swift之(一):关于swift与开发环境配置
一.什么是Swift? 1.Swift 是一种新的编程语言,用于编写 iOS 和 OS X 应用. 2.Swift 结合了 C 和 Objective-C 的优点并且不受 C 兼容性的限制. 3.Sw ...
- 開始学习swift开发
近期要開始学习swift开发了,接下来的日子,会记录学习swift的历程.
- 学习swift语言的快速入门教程推荐
随着苹果产品越来越火爆,苹果新推出的swift必定将在很大程度上代替oc语言.学好swift语言,对于IOS工程师来讲,已经是一门必备技能. 有一些比较好的英文版教程,值得学习. 1. Swift T ...
- 一步一步学习Swift之(二):好玩的工具playground与swfit基础语法
playground好于在于能一边写代码一边看到输出的常量变量的值.不需要运行模拟器. 我们来试一下该工具的用法. 打开xcode6开发工具,选择Get started with a playgrou ...
- 開始学习swift,资料汇总帖
最近開始学习swift,以后mac和ios开发就指望它,曾经学oc半途而废了.主要原因是oc等语法实在能适应,如今有swift了.语法有js,scala,python,c++,oc等语言的影子,又一次 ...
- Swift-如何快速学习Swift
关于本文: 1.说明本文写作的目的 2.整理了Swift的基本语法树 3.看图作文 一.写作目的 昨天看了一个知识专栏,作者讲述的是“如何研究性的学习”.整个课程1个小时9分钟,花了我19块人民币.其 ...
随机推荐
- ABAP ALV DEMO示例源码
关于ALV表格颜色,感觉这种需求在项目中用到的时候不是很多,但是前一段时间面试的时候,面试官问了我关于ALV单元格颜色的问题. 以前了解过一点,回答的不是很好,后来百度了一下,大概了解了一些,今天工作 ...
- 如何在ubuntu下使用stage3d的硬件加速
最近想尝试一下心动的新游戏深渊,但是由于公司的电脑是ubuntu的,只要进游戏就提示说没有stage3d的硬件加速,于是google了一下,发现这么一篇文章 http://phoronix.com/f ...
- Can't connect to MySQL server on localhost (10061)解决方法
出现这种错误的原因是由于MySQL的服务被关闭的原因,重新启动一下服务就可以了,启动服务的操作如下: 右键[计算机]-[管理]
- 06 MDB将数据和dataGridView1绑定
附件:http://files.cnblogs.com/xe2011/dataGridView1_bindingNavigator1_bindingSource1.rar 实现功能 对.MDB文件进行 ...
- hdu 3586 Information Disturbing(树形dp + 二分)
本文出自 http://blog.csdn.net/shuangde800 题目链接: hdu-3586 题意 给一棵n个节点的树,节点编号为1-n,根节点为1.每条边有权值,砍掉一条边要花费 ...
- hadoop错误org.apache.hadoop.mapred.MapTask$NewOutputCollector@17bda0f2
错误: org.apache.hadoop.mapred.MapTask$NewOutputCollector@17bda0f2 java.io.IOException: Spill failed 错 ...
- mongnodb 启动脚本
开始用mongodb建立一套监控体系,安装解压即可.附上编写的mongodb启动管理脚本. 建议 mkdir sbin 目录,放到sbin目录下.废话少说,代码如下: #!/bin/bash MONG ...
- pnd3
这两天重写了,消除后本身的下落计算还有问题,新产生的块下落和消除已经OK了.消除算法真的很要命.最后还是回归最开始的想法,用递归的方式不断的SPREAD来得到消除的数据.快到月底了,得勤写写了,要不找 ...
- Windows2012中安装域控(DC) + SQL Server 2014 + TFS 2015
安装域控(DC) 修改计算机名 修改固定IP 添加角色 选择“Role-based or feature-based installation” 选择本机 选择“Active Directory Do ...
- Linux安装QQ 2017
网上有很多wineQQ,是基于2012或者2013做的,然而当安装好后登录他会提示版本过来,我在优麒麟的应用商店里找到了一个基于国际版QQ的Wine版本,这里说下安装过程. 先上两张成果图: 下载地址 ...