iOS - Swift Closure 闭包
1、Closure
闭包在 Swift 中非常有用。通俗的解释就是一个 Int 类型里存储着一个整数,一个 String 类型包含着一串字符,同样,闭包是一个包含着函数的类型。有了闭包,你就可以处理很多在一些古老的语言中不能处理的事情。这是因为闭包使用的多样性,比如你可以将闭包赋值给一个变量,你也可以将闭包作为一个函数的参数,你甚至可以将闭包作为一个函数的返回值。它的强大之处可见一斑。在 Swift 的很多文档教材中都说函数是“一等公民”,起初我还不是很理解“一等公民”是什么意思,但当我理解了闭包以及它的强大功能后,我恍然大悟、茅塞顿开、醍醐灌顶。原来闭包的这些特性就是“一等公民”的特性啊!
闭包是功能性自包含模块,可以在代码中被传递和使用。一段程序代码通常由常量、变量和表达式组成,然后使用一对花括号“{}” 来表示闭合并包裹着这些代码,由这对花括号包裹着的代码块就是一个闭包。Swift 中的闭包与 C 和 Objective-C 中的 Block 以及其他一些编程语言中的 lambdas 比较相似。Block 和闭包的区别只是语法的不同而已,而且闭包的可读性比较强。
闭包是引用类型,无论你将函数/闭包赋值给一个常量还是变量,实际上都是在将常量/变量设置为对应函数/闭包的引用,这也意味着如果你将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包。
1)在 Swift 语言中有三种闭包形式:
- 全局函数:是一个有名字但不会捕获任何值的闭包。
- 嵌套函数:是一个有名字并可以捕获到其封闭函数域内的值的闭包。
- 匿名闭包:闭包表达式是一个利用轻量级语法所写的,可以捕获其上下文中变量或常量值。
2)函数形式:
func myConpare(s1:String, s2:String) -> Bool { return s1 > s2 } let namesArray:Array = ["Jill", "Tim", "Chris"] let names = namesArray.sort(myConpare)3)一般形式:
{ (parameters参数) -> returnType返回类型 in statements }可以使用常量、变量、inout、可变参数、元组类型作为闭包的参数,但不能在闭包参数中设置默认值,定义返回值和函数返回值的类型相同。
闭包表达式中的 in 关键字表示闭包的参数和返回值类型定义已经完成,这些参数和返回值都将在下面的闭包函数体中得到处理。
let namesArray:Array = ["Jill", "Tim", "Chris"] let names = namesArray.sort { (s1:String, s2:String) -> Bool in return s1 > s2 }
4)参数类型隐藏形式:
Swift 中有类型推断的特性,所以我们可以去掉参数类型。
let namesArray:Array = ["Jill", "Tim", "Chris"] let names = namesArray.sort { (s1, s2) -> Bool in return s1 > s2 }
5)返回值类型隐藏形式:
Swift 中有类型推断的特性,所以我们可以去掉返回值类型。
let namesArray:Array = ["Jill", "Tim", "Chris"] let names = namesArray.sort { (s1, s2) in return s1 > s2 }
6)return 隐藏形式:
单行表达式的闭包可以通过隐藏关键字 return 来隐式地将单行表达式的结果作为返回值。
let namesArray:Array = ["Jill", "Tim", "Chris"] let names = namesArray.sort { (s1, s2) in s1 > s2 }
7)参数名省略形式:
闭包的使用非常的灵活,我们可以省略闭包参数列表中的参数的参数类型定义,被省略的参数类型会通过闭包函数的类型进行推断。同时,我们也可以在闭包函数体中通过使用闭包的参数名简写功能,直接使用
$0、$1、$2等名字就可以引用的闭包参数值。如果同时省略了参数名和参数类型,那么 in 关键字也必须被省略,此时闭包表达式完全由闭包函数体构成。let namesArray:Array = ["Jill", "Tim", "Chris"] let names = namesArray.sort { $0 > $1 }
8)trailing 闭包形式:
闭包可以做其他函数的参数,而且通常都是函数的最后一个参数。但是如果作为参数的这个闭包表达式非常长,那么很有可能会影响函数调用表达式的可读性,这个时候我们就应该使用 trailing 闭包。trailing 闭包和普通闭包的不同之处在于它是一个书写在函数参数括号之外(之后)的闭包表达式,函数会自动将其作为最后一个参数调用。
当函数有且仅有一个参数,并该参数是闭包时,不但可以将闭包写在 () 外,还可以省略 ()。Swift 2.2 中可以不管参数的个数完全省略 ()。
let namesArray:Array = ["Jill", "Tim", "Chris"] let names = namesArray.sort() { $0 > $1 }
9)闭包捕获:
闭包可以在其定义的上下文中捕获常量或变量,即使定义这些常量或变量的原作用域已经不存在,仍然可以在闭包函数体内引用和修改这些常量或变量,这种机制被称为闭包捕获。在 Swift 中闭包的最简单形式是嵌套函数。嵌套函数就可以捕获其父函数的参数以及定义的常量和变量,全局函数可以捕获其上下文中的常量或变量。
func increment(amount: Int) -> (() -> Int) { var total = 0 func incrementAmount() -> Int { // total 是外部函数体内的变量,这里是可以捕获到的 total += amount return total } // 返回的是一个嵌套函数(闭包) return incrementAmount } // 闭包是引用类型,所以 incrementByTen 声明为常量也可以修改 total let incrementByTen = increment(10) incrementByTen() // return 10,incrementByTen 是一个闭包 // 这里是没有改变对 increment 的引用,所以会保存之前的值 incrementByTen() // return 20 incrementByTen() // return 30 let incrementByOne = increment(1) incrementByOne() // return 1,incrementByOne 是一个闭包 incrementByOne() // return 2 incrementByTen() // return 40 incrementByOne() // return 3
iOS - Swift Closure 闭包的更多相关文章
- [ios][swift]使用swift闭包进行viewcontroller反向传值
闭包参考:http://c.biancheng.net/cpp/html/2285.html 闭包详解 传值参考:http://www.tuicool.com/articles/vy2uUz Sw ...
- Swift: 比较Swift中闭包传值、OC中的Block传值
一.介绍 开发者对匿名函数应该很清楚,其实它就是一个没有名字的函数或者方法,给人直观的感觉就是只能看到参数和返回值.在iOS开发中中,它又有自己的称呼,在OC中叫Block代码块,在Swift中叫闭包 ...
- iOS/Swift Tips 1
1.重写hitTest方法,干预iOS事件传递过程 如下所示,view上有一个button,button一半的frame在父类view bounds之外, 按照iOS系统默认的处理逻辑, 如果点击按钮 ...
- Swift:闭包
一.闭包的介绍 闭包表达式(Closure Expressions) 尾随闭包(Trailing Closures) 值捕获(Capturing Values) 闭包是引用类型(Closures Ar ...
- 4 .Swift函数|闭包
在编程中,我们常把能完成某一特定功能的一组代码,并且带有名字标记类型叫做函数,在C语言中,我们知道函数名就是一个指针,它指向了函数体内代码区的第一行代码的地址,在swift中也具有同样的功效. 在Sw ...
- Swift使用闭包表达式
Swift中的闭包表达式很灵活,其标准语法格式如下:{ (参数列表) ->返回值类型 in 语句组}其中,参数列表与函数中的参数列表形式一样,返回值类型类似于函数中的返回值类型,但不同的是 ...
- Swift函数|闭包
在编程中,我们常把能完成某一特定功能的一组代码,并且带有名字标记类型叫做函数,在C语言中,我们知道函数名就是一个指针,它指向了函数体内代码区的第一行代码的地址,在swift中也具有同样的功效. 在Sw ...
- Swift的闭包(一):闭包简介、闭包表达式的优化
定义:Closures are self-contained blocks of functionality that can be passed around and used in your co ...
- Building gRPC Client iOS Swift Note Taking App
gRPC is an universal remote procedure call framework developed by Google that has been gaining inter ...
随机推荐
- SPOOL、SQLLOADER数据导出导入的一点小总结
1.SQLLOADER的CONTROL文件 //**************************************************************************** ...
- [转]Using the Group Pane to Repeat Page Titles
转自:http://www.wiseowl.co.uk/blog/s148/group-pane-advanced-mode.htm Repeating Page Headers in Reporti ...
- 【JQGRID DOCUMENTATION】.学习笔记.1.安装jqGrid
前面介绍了怎么使用其MVC方式,很好用.不过,觉得还是只使用前段比较好. 1.1 如何安装 到http://www.trirand.com/blog/?page_id=6 下载. </html& ...
- ASP开发入门+实战电子书共50本 —下载目录
小弟为大家整理50个ASP电子书籍,有入门,也有实战电子书,做成了一个下载目录,欢迎大家下载. 资源名称 资源地址 ASP.NET开发实战1200例_第I卷 http://down.51cto.com ...
- String.Join 和 Distinct 方法 去除字符串中重复字符
Qualys项目中写到将ServerIP以“,”分割后插入数据库并将重复的IP去除后发送到服务器进行Scan,于是我写了下面的一段用来剔除重复IP: //CR#1796870 modify by v- ...
- asp.net 分页-利用后台直接生成html分页
一直想做一个属于自己的分页, 1:我试过用datapage,虽然是很好用,但是必须要配合datalist才能使用,感觉不太好 2:自己写分页控件,目前正在摸索中,关键是怎么分页的问题,有的是用data ...
- [HTML]网页开发学习笔记
为了要开发一套教学使用的教师管理系统,(客户需求使用网页做教师控制端口)我便学习了一下HTML网页开发. 很不错的学习开发的网站:http://www.w3school.com.cn/index.ht ...
- java 1G大文件复制
对比几种复制方法 复制的文件是980m的txt文件 1. FileChannel 方法 代码: public static void mappedBuffer() throws IOExceptio ...
- 使用jquery再次封装ajax
$.fn.ajaxSend = function (type, url, postdata, onSuccess) { $.ajax({ async: false, url: url, type: t ...
- 国内下Android源码地址
1 Android 4.4 with kernel: http://pan.baidu.com/s/1bnuDtHt 下载后,请务必阅读 必读.txt 2 android 5.0源码下载 http:/ ...