版本记录
版本号 | 时间 |
---|---|
V1.0 | 2017.08.01 |
前言
我是swift2.0的时候开始接触的,记得那时候还不是很稳定,公司的项目也都是用oc做的,并不对swift很重视,我自己学了一段时间,到现在swift3.0+已经出来了,自己平时也不写,忘记的也差不多了,正好项目这段时间已经上线了,不是很忙,我就可以每天总结一点了,希望对自己对大家有所帮助。在总结的时候我会对比oc进行说明,有代码的我会给出相关比对代码。
1. swift简单总结(一)—— 数据简单值和类型转换
2. swift简单总结(二)—— 简单值和控制流
3. swift简单总结(三)—— 循环控制和函数
4. swift简单总结(四)—— 函数和类
5. swift简单总结(五)—— 枚举和结构体
6. swift简单总结(六)—— 协议扩展与泛型
7. swift简单总结(七)—— 数据类型
8. swift简单总结(八)—— 别名、布尔值与元组
9. swift简单总结(九)—— 可选值和断言
10. swift简单总结(十)—— 运算符
11. swift简单总结(十一)—— 字符串和字符
12. swift简单总结(十二)—— 集合类型之数组
13. swift简单总结(十三)—— 集合类型之字典
14. swift简单总结(十四)—— 控制流
15. swift简单总结(十五)—— 控制转移语句
16. swift简单总结(十六)—— 函数
17. swift简单总结(十七)—— 闭包(Closures)
18. swift简单总结(十八)—— 枚举
19. swift简单总结(十九)—— 类和结构体
20. swift简单总结(二十)—— 属性
21. swift简单总结(二十一)—— 方法
22. swift简单总结(二十二)—— 下标脚本
23. swift简单总结(二十三)—— 继承
24. swift简单总结(二十四)—— 构造过程
25. swift简单总结(二十五)—— 构造过程
26. swift简单总结(二十六)—— 析构过程
27. swift简单总结(二十七)—— 自动引用计数
28. swift简单总结(二十八)—— 可选链
29. swift简单总结(二十九)—— 类型转换
30.swift简单总结(三十)—— 嵌套类型
扩展 - Extensions
扩展就是向一个已有的类、结构体或枚举类型添加新功能,这包括在没有权限获取原始源代码的情况下扩展类型的能力(即逆向建模),扩展和OC
中的分类类似,不过不同的是,swift
的扩展是没有名字的。
在swift
中的扩展可以:
- 添加计算型属性和计算静态属性
- 定义实例方法和类型方法
- 提供新的构造器
- 定义下标
- 定义和使用新的嵌套类型
- 使一个已有类型符合某个协议
注意:如果你定义了一个已有类型添加新功能,那么这个新功能对该类型的所有已有实例中都是可用的,即使他们是在你的这个扩展的前面定义的。
本篇主要从以下几个方面进行说明。
- 扩展语法
- 计算型属性
- 构造器
- 方法
- 下标
- 嵌套类型
扩展语法 - Extension Syntax
下面先看一下如何声明一个扩展。
extension SomeType {
//加到SomeType的新功能代码
}
一个扩展可以扩展一个已有来行,使其能够适配一个或多个协议,当这种情况发生时,协议的名字应该完全按照类或结构体的名字方式进行书写。
extension SomeType : SomeProtocol, AnotherProtocol {
//加到SomeType的新功能代码
}
按照这种方式添加的协议遵循者(protocol comformance)
被称为在扩展中添加协议遵循者。
计算性属性 - Computed Properties
扩展可以向已有类型添加计算性实例属性和计算型类型属性,下面就是向swift
内部的Double
类型加入几个计算型实例属性。
下面看一下代码。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
let oneInch = 25.4.mm
print("One inch is \(oneInch) meters")
let threeFeet = 3.ft
print("Three feet is \(threeFeet) meters")
}
}
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
}
}
下面看输出结果
One inch is 0.0254 meters
Three feet is 0.914399970739201 meters
这些属性是只读的计算型属性,所以考虑他们不用get
关键字,它们的返回值是Double
类型。
构造器 - Initializers
扩展可以向已有类型添加新的构造器,这可以让你扩展其他类型,将你自己的定制类型作为构造参数,或者提供该类型的原始实现中没有包含的额外初始化选项。
扩展能向类中添加新的便利构造器,但是它们不能向类中添加新的指定构造器或析构函数,指定构造器和析构函数必须总是由原始的类实现来提供。
下面的例子给出的就是描述几何矩形的定制结构体Rect
,下面看一下简单的代码。
struct Size {
var width = 0.0, 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 aRect = Rect(origin: Point(x : 2.0, y : 2.0 ), size: Size(width: 5.0, height: 5.0))
你可以提供一个额外的使用特殊中心点和大小的构造器来扩展Rect
结构体。
extension Rect{
init(center : Point, size : Size) {
let originX = center.x - size.width * 0.5
let originY = center.y - size.height * 0.5
self.init(origin: Point(x : originX, y : originY), size: size)
}
}
这个新的构造器首先根据提供的center
和size
值计算一个合适的点,然后调用该结构体自动的成员构造器init(origin: size:)
,该构造器将新的原点和大小存到了合适的属性中。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
let centerRect = Rect(center: Point(x : 4.0, y : 4.0), size: Size(width: 3.0, height: 3.0))
print(centerRect)
}
}
下面看输出结果
Rect(origin: JJSwift.Point(x: 2.5, y: 2.5), size: JJSwift.Size(width: 3.0, height: 3.0))
注意:如果你使用扩展提供了一个新的构造器,你依旧有责任保证构造过程能够让所有势力完全初始化。
方法 - Methods
扩展可以向已有类型添加新的实例方法和类型方法,下面的例子向Int
类型添加一个新的实例方法repetitions
。
extension Int{
func repetitions(task : () -> ()) {
for i in 0..<self {
task()
}
}
}
这个repetitions
方法使用了一个() -> ()
类型的单参数,表明函数没有参数而且没有返回值,定义该扩展后,你就可以对任意整数调用repetitions
方法,进行多次执行某个任务。
下面我们就调用下试试。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
3.repetitions {
print("Hello")
}
}
}
下面看输出结果
Hello
Hello
Hello
上面其实就是尾随闭包。
1. 修改实例方法 - Mutating Instance Methods
通过扩展添加的实例方法也可以修改该实例本身,结构体和枚举类型中修改self
或其属性的方法必须将该实例方法标注为mutating
,正如来自原始实现的修改方法一样。
下面的例子给Int
类型添加了一个新的名字为square
的修改方法,来实现一个原始值的平方计算。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
var someInt = 3
someInt.square()
print(someInt)
}
}
extension Int{
mutating func square(){
self = self * self
}
}
下面看输出结果
9
下标 - Subscripts
扩展可以向一个已有类型添加新下标,看下面的例子,向Int
添加了一个整型下标,该下标[n]
返回十进制数字从右向左的第n
个数字。例如123456789
中 [0]
返回9
。
下面看一下代码。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
print(123456789[0])
}
}
extension Int{
subscript( digitIndex : Int) -> Int{
var index = digitIndex
var decimalBase = 1
while index > 0 {
decimalBase *= 10
index -= 1
}
return (self/decimalBase) % 10
}
}
下面看输出结果
9
如果该Int
值没有足够的位数,下标越界,那么上述实现的下标会返回0
,因为它会在数字左边自动补0
。
print(123456789[10])
下面看输出结果
0
嵌套类型 - Nested Types
扩展可以向已有的类、结构体和枚举添加新的嵌套类型。
extension Character{
enum Kind {
case Vowel, Consonaut, Other
}
var kind : Kind{
switch String(self).lowercased() {
case "a", "e", "i", "o", "u":
return .Vowel
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m","n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
return .Consonaut
default:
return .Other
}
}
}
该例子向Character
添加了新的嵌套枚举,这个名为kind
的枚举表示特定字符的类型,这个例子还添加了一个新的计算实例属性kind
,用来返回合适的kind
枚举成员。
下面我们调用一下。
class JJPracticeVC: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
view.backgroundColor = UIColor.lightGray
printLetterKinds(word: "Hello")
}
}
func printLetterKinds(word : String){
print("\(word) is made up of the following kinds of letters")
for character in word.characters {
switch character.kind {
case .Vowel:
print("vowel")
case .Consonaut:
print("consonaut")
default:
print("other")
}
}
}
下面看输出结果
Hello is made up of the following kinds of letters
consonaut
vowel
consonaut
consonaut
vowel
这个很好理解,相信大家都可以看的明白。
后记
未完,待续~~~