首页 > 其他 > 详细

Swift的闭包,枚举,类和结构体

时间:2014-06-26 08:13:01      阅读:411      评论:0      收藏:0      [点我收藏+]

闭包(Closures)


使用过其他语言的应该对代码块并不陌生,Swift中的闭包与C,OC中的Block相似。
表示自包含的函数代码块,可以在代码中传递和使用。
并且可以捕获和存储上下文的变量以及常量值,Swift会为你进行捕获相关的内存操作。


上一篇文章提到的函数,也是一种特殊的闭包,具体在:
全局函数是有名字但是不会捕获任何值的闭包。
嵌套函数是有名字且可以捕获域内值的闭包。
闭包表达式是利用轻量级语法写的可以捕获上下文值的匿名闭包。

基本语法

表达式的一般语法以及简化过程
bubuko.com,布布扣

上面罗列了同一个行为的五种写法,也标明了简化方法适用的情景。

尾随闭包


上面那个闭包若使用尾随闭包的方式来写,则表现为:
reversed = sort(names) {$0 > $1}

通常我们会把具有多行的闭包表达式写入尾随闭包。
例如Array的map方法可以对数组内的每一个元素调用一次闭包,返回一个新的数组。
bubuko.com,布布扣

这里捕获了numbers数组中的每个值并将output映射到一个新的strings数组中。


值捕获


闭包可以在其上下文捕获一些值,即使原域已经不存在。上面提到嵌套函数是有名字可以捕获域内值的闭包。Swift中最简单的闭包形式即是嵌套函数。
bubuko.com,布布扣

这里定义了一个嵌套函数makeIncrementor,里面记录了一个变量runningTotal,嵌套在里面的函数可以捕获这个值并将其持有保留住。
bubuko.com,布布扣

但是如果新声明了一个相同函数的变量/常量引用,则其runningTotal并不共享
bubuko.com,布布扣


闭包是引用类型,上面声明的常量是指向闭包内容的一个引用,而并非闭包内容本身。


枚举


Swift的枚举十分灵活,case中的值可以是字符串,字符,整型或者浮点型。并且可以指定任何类型的相关值存储到枚举成员中。
在Swift里,枚举是一等类型(first-class),它支持类所支持的特性(除了继承),你可以为它定义一些函数让其富有行为等等。

基本语法

bubuko.com,布布扣

当我们已经确定了其是CompassPoint的时候,可以直接使用.Value省略枚举名的形式赋值。

switch匹配
bubuko.com,布布扣

相关值

前面提到过,我们可以为其指定任意类型的相关值存储到枚举成员中。
来看下面这个例子
bubuko.com,布布扣

我们给BarCode枚举存储了一些相应case的相关值,并且可以利用绑定值的方式去访问它,如在switch中定义了个常量identifier来获取Barcode中QRCode的相关值。

原始值

在Swift中,枚举并不会像c,objective-c中的枚举在你未声明枚举值的情况下隐式的赋值0,1,2...只有我们给其赋值时才会猜测其值,但是也仅限于Int。
Swift为其定义了方法来访问原始值toRaw()或者通过fromRaw(value)访问其枚举成员。
bubuko.com,布布扣

由于我们的枚举中并没有5对应的成员,所以其为nil。但如果换为3,则是Green。

那如果枚举成员是String呢?会不会也会猜测值?当然是不太可能了- -
编译器会报错
bubuko.com,布布扣

非integer必须要给其赋值才可以。


类与结构体


定义,实例声明与属性


bubuko.com,布布扣

由于这里并没有设置自定义的指定构造器,所以可以直接使用默认的方式()来初始化一个实例。

访问设置属性则使用点语法,不过与Ojbective--C不同的是,Swift允许对结构体的子属性直接赋值。另外一个不同则是Swift类不需要.h接口文件。
bubuko.com,布布扣

在OC中我们想修改Rect.Origin的x值经常需要赋一个新的origin给rect,而Swift中则可以直接修改了。

在Swift中结构体,枚举和类都可以通过写一些成员函数来为其添加行为。
构造时则稍有不同,结构体可以为其提供逐一成员构造器。
bubuko.com,布布扣

这是系统自动提供的,而类则没有提供。

值类型和引用类型


结构体,枚举和类另外主要不同的一点是类型。
结构体和枚举为值类型,类则是引用类型。

值类型指在赋值传递的时候,系统会自动为其拷贝一个新值并传递给新声明的变量或常量。
bubuko.com,布布扣

我们注意在将hd赋值给cinema后立即cinema的width进行了修改,但是再访问hd.width还是原来的值1920.说明只是将hd的拷贝赋给了cinema而并不是hd本身。

引用类型这是将新的变量或常量指向了原来的对象,而并非拷贝对象值之后进行赋值。
bubuko.com,布布扣

这里修改了frameRate,再访问原来变量的frameRate发现也发生了变化。原因在于他们都指向了同一块堆内存。


在Swift中,判定引用相等引人了一个恒等符号"===",来判定是否引用同一实例,不引用同一实例则为"!=="(不等价于)
那么"==="和"=="的不同在于哪里呢?
等价于("===")表示两个类类型的常量或变量引用同一个实例。
而"=="表示两个实例的值是否相等,判定需要遵照类设计者定义的判定标准。

由于结构体是值类型,我们不使用等价于进行判断。


类和结构体的异同和选择


首先来看类和结构体的相同点:
定义属性用于存储值
定义方法用于提供功能
定义附属脚本(subindex)用于访问值
定义构造器用于初始化值和配置
通过扩展以增加默认实现的功能
符合协议以对某类提供标准功能

不同点在于:(类)
继承允许一个类继承另一个类的特征
类型转换允许在运行时检查和解释一个类实例的类型
解构器(析构过程会提到)允许一个类实例释放任何其所被分配的资源
引用计数允许对一个类的多次使用

则我们通常在下列情况下考虑结构体:
用来封装少量相关简单数据值
预计数据传递会被拷贝而不是引用
结构体中的值类型属性也会被拷贝
不需要继承或被继承特征和行为

集合类型的赋值和拷贝行为


上面说到了值类型和引用类型。在Swift中,集合类型字典和数组在后台均以结构体实现,但是他们的情况稍微有些特殊。
虽然通常值类型的赋值行为都是通过拷贝实现的,我们也不需要害怕过多使用内存而带来的性能问题,Swift会管理所有的值拷贝以确保性能最优化。

字典的赋值和拷贝行为

字典的key/value中,若其为值类型则拷贝值,引用类型则拷贝引用。
bubuko.com,布布扣

数组的赋值和拷贝行为


相比字典数组要复杂的多,当操作数组内容时,数组能提供接近C语言的性能,并且保证拷贝只有在必要时发生。

那么必要时是什么时候呢?是改变数组长度的时候,例如调用了append(), insert(), remove()等函数,数组的拷贝才会发生,不改变时则属于引用传递。

bubuko.com,布布扣

有的时候我们想确保数组的唯一性,这时可以调用unshare方法使其变成唯一拷贝。强制拷贝则使用copy方法。但是copy在任何情况下都会创建新的拷贝,而unshare则会确保唯一引用。


在判定数组是否相同时我们也可以使用"==="来判定两个数组是否共用相同的空间或者元素。
bubuko.com,布布扣

因为他们都非共用空间,所以返回都是false.



有关闭包,枚举,结构体和类的基础知识都讲解完毕。欢迎勘误和讨论。

Swift的闭包,枚举,类和结构体,布布扣,bubuko.com

Swift的闭包,枚举,类和结构体

原文:http://blog.csdn.net/cocoarannie/article/details/33785571

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!