闭包(Closures)


使用过其它语言的应该对代码块并不陌生,Swift中的闭包与C,OC中的Block相似。
表示自包括的函数代码块。能够在代码中传递和使用。

而且能够捕获和存储上下文的变量以及常量值,Swift会为你进行捕获相关的内存操作。


上一篇文章提到的函数。也是一种特殊的闭包。详细在:
全局函数是有名字可是不会捕获不论什么值的闭包。
嵌套函数是有名字且能够捕获域内值的闭包。
闭包表达式是利用轻量级语法写的能够捕获上下文值的匿名闭包。

基本的语法

表达式的一般语法以及简化过程


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

跟随闭包


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

通常我们会把具有多行的闭包表达式写入跟随闭包。

比如Array的map方法能够对数组内的每个元素调用一次闭包。返回一个新的数组。


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



值捕获


闭包能够在其上下文捕获一些值,即使原域已经不存在。

上面提到嵌套函数是有名字能够捕获域内值的闭包。

Swift中最简单的闭包形式即是嵌套函数。



这里定义了一个嵌套函数makeIncrementor,里面记录了一个变量runningTotal,嵌套在里面的函数能够捕获这个值并将其持有保留住。



可是假设新声明了一个同样函数的变量/常量引用,则其runningTotal并不共享



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



枚举


Swift的枚举十分灵活,case中的值能够是字符串。字符。整型或者浮点型。

而且能够指定不论什么类型的相关值存储到枚举成员中。

在Swift里,枚举是一等类型(first-class),它支持类所支持的特性(除了继承)。你能够为它定义一些函数让其富有行为等等。


基本的语法



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

switch匹配


相关值

前面提到过。我们能够为其指定随意类型的相关值存储到枚举成员中。
来看以下这个样例


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


原始值

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


因为我们的枚举中并没有5相应的成员,所以其为nil。但假设换为3。则是Green。

那假设枚举成员是String呢?会不会也会推測值?当然是不太可能了- -
编译器会报错


非integer必需要给其赋值才干够。


类与结构体


定义,实例声明与属性




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


訪问设置属性则使用点语法,只是与Ojbective--C不同的是,Swift同意对结构体的子属性直接赋值。

另外一个不同则是Swift类不须要.h接口文件。



在OC中我们想改动Rect.Origin的x值常常须要赋一个新的origin给rect,而Swift中则能够直接改动了。


在Swift中结构体,枚举和类都能够通过写一些成员函数来为其加入行为。

构造时则稍有不同,结构体能够为其提供逐一成员构造器。


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

值类型和引用类型


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

结构体和枚举为值类型,类则是引用类型。

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


我们注意在将hd赋值给cinema后马上cinema的width进行了改动,可是再訪问hd.width还是原来的值1920.说明仅仅是将hd的拷贝赋给了cinema而并非hd本身。

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


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



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

而"=="表示两个实例的值是否相等。判定须要遵照类设计者定义的判定标准。


因为结构体是值类型。我们不使用等价于进行推断。



类和结构体的异同和选择


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

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

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

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


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

字典的赋值和拷贝行为

字典的key/value中。若其为值类型则拷贝值。引用类型则拷贝引用。


数组的赋值和拷贝行为


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

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



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



在判定数组是否同样时我们也能够使用"==="来判定两个数组是否共用同样的空间或者元素。



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



有关闭包,枚举,结构体和类的基础知识都解说完成。

欢迎勘误和讨论。


Swift的闭包,枚举,类和结构体的更多相关文章

  1. swift学习笔记3——类、结构体、枚举

    之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...

  2. 【Swift学习】Swift编程之旅---类和结构体(十三)

    与其他编程语言所不同的是,Swift 并不要求你为自定义类和结构去创建独立的接口和实现文件.你所要做的是在一个单一文件中定义一个类或者结构体,系统将会自动生成面向其它代码的外部接口. 注意:通常一个类 ...

  3. swift学习笔记之-类和结构体

    //类和结构体 import UIKit //类和结构体 /* 1.枚举enum.结构体struct和String.Array.Dictionary类型,都属于值传递类型,被赋值给新的常量或变量时传递 ...

  4. Swift语法学习之 类和结构体

    类和结构体 本页包括内容: 类和结构体对照 结构体和枚举是值类型 类是引用类型 类和结构体的选择 集合(collection)类型的赋值与复制行为 与其他编程语言所不同的是,Swift 并不要求你为自 ...

  5. Swift学习笔记(11)--类与结构体

    类与结构是编程人员在代码中会经常用到的代码块.在类与结构中可以像定义常量,变量和函数一样,定义相关的属性和方法以此来实现各种功能. 和其它的编程语言不太相同的是,Swift不需要单独创建接口或者实现文 ...

  6. Swift3.0P1 语法指南——类和结构体

    原档:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programmi ...

  7. 站在OC的基础上快速理解Swift的类与结构体

    阅读此文章前,您已经有一定的Object-C语法基础了!) 2014年,Apple推出了Swift,最近开始应用到实际的项目中. 首先我发现在编写Swift代码的时候,经常会遇到Xcode不能提示,卡 ...

  8. Swift面向对象基础(上)——Swift中的类和结构体(上)

    学习来自<极客学院> import Foundation //1.定义类和结构体 /* [修饰符]calss 类名{ 零到多个构造器 零到多个属性 零到多个方法 零到多个下标 } 修饰符可 ...

  9. swift 类 与 结构体

    这两天突然有人问我  swift里面 类和 结构体  有什么区别? 说实在的本人目前不太看好swift,相信很多人也是,oc 都 很成熟了. 本人目前不打算深入了解swift的原因swift  语言 ...

随机推荐

  1. Html标记语言学习一2017年6月12日

    今天主要学习了 frame的用法. <frameset> 可以将网页分成几个不同的部分 使用 cols  和  rows 两种标记.前者是列,后者是行 <frame/>  单标 ...

  2. IE模式下EasyUI Combobox无效问题

    近期开发过程中遇到IE浏览器Combobox无法正常加载问题. 经过一番百度说IE渲染过快导致页面渲染完了easyUI Combobox还没有加载.设置延迟加载后依旧无效. 后将input标签的Cla ...

  3. 2015 Multi-University Training Contest 2 Buildings

    Buildings Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total ...

  4. 关于bom ef+bb+bf的问题

    今天在商品详细页头部出现了一行空白,各种尝试无果,最后怀疑是不是bom头的问题,经过断点跟踪调试逐步缩小范围,果然最后发现是一个语言包文件的开头有 ef bb bf样式的字节,用ultraedit另存 ...

  5. MATLAB曲线拟合

    转自原文 MATLAB曲线拟合 曲线拟合 实例:温度曲线问题 气象部门观测到一天某些时刻的温度变化数据为: t 0 1 2 3 4 5 6 7 8 9 10 T 13 15 17 14 16 19 2 ...

  6. HTML5实战与剖析之媒体元素(3、媒体元素的事件及方法)

    HTML5中的媒体元素除了拥有非常多的属性之外,video标签和audio标签还能够出发非常多事件和方法. 这些方法监控着不同的属性的变化,这些变化有可能是媒体播放的结果,也可能是用户操作媒体的结果. ...

  7. android中的AlertDialog具体概述

    android的AlertDialog具体解释 AlertDialog的构造方法所有是Protected的.所以不能直接通过new一个AlertDialog来创建出一个AlertDialog. 要创建 ...

  8. 【LeetCode OJ 34】Search for a Range

    题目链接:https://leetcode.com/problems/search-for-a-range/ 题目:Given a sorted array of integers, find the ...

  9. 操作指定文件格式的10个Perl CPAN模块

    在Perl开发中,非常可能会碰到一些不同格式的文件--XML.PDF.CSV及RSS文件等,和一些不同的二进制数据格式.Perl应用程序须要操作这些文件,对它们进行读写. 此时.能够求助于全面Perl ...

  10. Node.js能够做什么?

    正如 JavaScript 为client而生.Node.js 为网络而生.Node.js 能做的远不止开发一个网 站那么简单,使用 Node.js,你能够轻松地开发:  具有复杂逻辑的站点:  ...