swift学习笔记之-闭包
//闭包
import UIKit
/*闭包(Closures):
函数、闭包、类都是引用类型(引用类型的实例赋值给变量或常量时,得到的都是该实例的引用,而值类型的实例变量得到的是独立的值的拷贝)
1.闭包是自包含的函数代码块,可以在代码中被传递和使用,与匿名函数比较相似,嵌套函数也是一种闭包
2.闭包可以捕获和存储其所在上下文中任意常量和变量的引用。这就是所谓的闭合并包裹着这些常量和变量,俗称闭包
在函数章节中介绍的全局和嵌套函数实际上也是特殊的闭包,闭包采取如下三种形式之一:
1.全局函数是一个有名字但不会捕获任何值的闭包
2.嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包
3.闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的匿名闭包
Swift 的闭包表达式拥有简洁的风格,并鼓励在常见场景中进行语法优化,主要优化如下:
1.利用上下文可推断参数和返回值类型,则可省略其类型定义
2.隐式返回单表达式闭包,即单表达式闭包可以省略return关键字
3.若参数类型可推断,则参数名称可缩写,省略对参数的定义,直接通过$0,$1,$2...来顺序调用闭包的参数,in关键字也同样可以被省略
4.尾随(Trailing)闭包语法
闭包表达式语法有如下一般形式:{类型 in 主体}
{ (parameters) -> returnType in
statements
}
闭包表达式语法:可以使用常量、变量和inout类型作为参数,不能提供默认值。也可以在参数列表的最后使用可变参数。元组也可以作为参数和返回值。
尾随闭包(Trailing Closures):如果您需要将一个很长的闭包表达式作为最后一个参数传递给函数,可以使用尾随闭包来增强函数的可读性
非逃逸闭包(Nonescaping Closures)
1.当一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸
2.当你定义接受闭包作为参数的函数时,你可以在参数名之前标注@noescape,用来指明这个闭包是不允许“逃逸”出这个函数的
3.将闭包保存在一个在函数外部定义的变量中,再通过这个变量来做为函数的参数,这样能使闭包“逃逸”出函数,这个闭包可以在函数返回之后被调用
自动闭包(Autoclosures)
1.自动闭包是一种自动创建的闭包,用于包装传递给函数作为参数的表达式。这种闭包不接受任何参数,当它被调用的时候,会返回被包装在其中的表达式的值。这种便利语法让你能够用一个普通的表达式来代替显式的闭包,从而省略闭包的花括号。
2.自动闭包让你能够延迟求值,因为代码段不会被执行直到你调用这个闭包。延迟求值对于那些有副作用(Side Effect)和代价昂贵的代码来说是很有益处的,因为你能控制代码什么时候执行。
3.通过将参数标记为@autoclosure将参数转化为一个自动闭包,@autoclosure特性暗含了@noescape特性,这个特性在非逃逸闭包一节中有描述。如果你想让这个闭包可以“逃逸”,则应该使用@autoclosure(escaping)特性.
*/
//=======sort()方法==========
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backwards(s1: String, s2: String) -> Bool {
return s1 > s2
}
var reversed = names.sort(backwards)
// reversed 为 ["Ewa", "Daniella", "Chris", "Barry", "Alex"]
//====以下是闭包表达式写法,功能一样
reversed = names.sort( { (s1: String, s2: String) -> Bool in return s1 > s2 } )
//根据上下文推断参数类型为(String,String)->Bool,所以可以省略
reversed = names.sort( { s1, s2 in return s1 > s2 } )
//单行表达式闭包可以通过省略return关键字来隐式返回单行表达式的结果
reversed = names.sort( { s1, s2 in s1 > s2 } )
//Swift 自动为内联闭包提供了参数名称缩写功能,您可以直接通过$0,$1,$2来顺序调用闭包的参数,以此类推.如果您在闭包表达式中使用参数名称缩写,您可以在闭包参数列表中省略对其的定义,并且对应参数名称缩写的类型会通过函数类型进行推断。in关键字也同样可以被省略
reversed = names.sort( { $0 > $1 } )
//如果参数类型和返回值类型正好与函数所需要的相符合,如sort函数,可以简单地传递一个大于号,Swift 可以自动推断出您想使用大于号的字符串函数实现:
reversed = names.sort(>)
//使用尾随闭包
reversed = names.sort() { $0 > $1 } //可以省略()
reversed = names.sort { $0 > $1 }
//=========Array类型中的map()映射方法========
let digitNames = [
0: "Zero", 1: "One", 2: "Two", 3: "Three", 4: "Four",
5: "Five", 6: "Six", 7: "Seven", 8: "Eight", 9: "Nine"
]
let numbers = [16, 58, 510]
let strings = numbers.map { //因为闭包比较长,所以使用尾随闭包,省略了map方法的()
(var number) -> String in //将整个闭包作为map()的参数,output传入map方法中
var output = ""
while number > 0 {
output = digitNames[number % 10]! + output
number /= 10
}
return output
}
// strings 常量被推断为字符串类型数组,即 [String]
// 其值为 ["OneSix", "FiveEight", "FiveOneZero"]
//=============自动闭包,延时求值==================
var customersInLine = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
print(customersInLine.count)
// prints "5"
let customerProvider = { customersInLine.removeAtIndex(0) }
print(customersInLine.count)
// prints "5"
print("Now serving \(customerProvider())!") //此处调用才计算闭包的值,customerProvider是一个函数,所以调用他要加()
// prints "Now serving Chris!"
print(customersInLine.count)
// prints "4"
//尽管在闭包的代码中,customersInLine的第一个元素被移除了,不过在闭包被调用之前,这个元素是不会被移除的。如果这个闭包永远不被调用,那么在闭包里面的表达式将永远不会执行,那意味着列表中的元素永远不会被移除。请注意,customerProvider的类型不是String,而是() -> String,一个没有参数且返回值为String的函数
//======将闭包作为参数传递给函数时,你能获得同样的延时求值行为
//customersInLine is ["Alex", "Ewa", "Barry", "Daniella"]
func serveCustomer(customerProvider:()->String) {
print("Now serving \(customerProvider())!")
}
serveCustomer( { customersInLine.removeAtIndex(0) } )
// prints "Now serving Alex!"
//=========@autoclosure转化为自动闭包=====
// customersInLine is ["Ewa", "Barry", "Daniella"]
func serveCustomer(@autoclosure customerProvider: () -> String) {
print("Now serving \(customerProvider())!")
}
serveCustomer(customersInLine.removeAtIndex(0))
// prints "Now serving Ewa!"
//=========@autoclosure(escaping)可逃逸的自动闭包====
// customersInLine is ["Barry", "Daniella"]
var customerProviders: [() -> String] = []
func collectCustomerProviders(@autoclosure(escaping) customerProvider: () -> String) {
customerProviders.append(customerProvider)
}
collectCustomerProviders(customersInLine.removeAtIndex(0))
collectCustomerProviders(customersInLine.removeAtIndex(0))
print("Collected \(customerProviders.count) closures.")
// prints "Collected 2 closures."
for customerProvider in customerProviders {
print("Now serving \(customerProvider())!")
}
// prints "Now serving Barry!"
// prints "Now serving Daniella!"
swift学习笔记之-闭包的更多相关文章
- Swift学习笔记之闭包
		
简介 (真的很简) 闭包的完整形态是这个样子的: { (parameters) -> returnType in statements } 写在一行里就是这样: {(parameters) -& ...
 - Swift学习笔记(9)--闭包
		
1.闭包表达式: { (parameters) -> returnType in statements } 注1.闭包表达式语法可以使用常量.变量和inout类型作为参数,不提供默认值. 也可以 ...
 - 【swift学习笔记】二.页面转跳数据回传
		
上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...
 - Swift学习笔记(一)搭配环境以及代码运行成功
		
原文:Swift学习笔记(一)搭配环境以及代码运行成功 1.Swift是啥? 百度去!度娘告诉你它是苹果最新推出的编程语言,比c,c++,objc要高效简单.能够开发ios,mac相关的app哦!是苹 ...
 - swift学习笔记2——函数、闭包
		
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
 - Swift学习笔记一
		
最近计划把Swift语言系统学习一下,然后将MagViewer用这种新语言重构一次,并且优化一下,这里记录一下Swift的学习笔记. Swift和Objective-C相比,在语法和书写形式上做了很多 ...
 - 记录:swift学习笔记1-2
		
swift还在不断的更新做细微的调整,都说早起的鸟儿有虫吃,那么我们早点出发吧,趁着国内绝大多数的coder们还没有开始大范围普遍应用. 网上有些大神说:swift很简单!我不同意这个观点,假如你用h ...
 - swift学习笔记5——其它部分(自动引用计数、错误处理、泛型...)
		
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
 - swift学习笔记4——扩展、协议
		
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
 
随机推荐
- apache2.4 以上设定gzip压缩
			
国内很多文章都是抄来抄去,用不成,用我这个就可以了 编辑 http.conf 文件 去掉 #LoadModule headers_module modules/mod_headers.so 前面的注释 ...
 - EDM博主笔记:EDM邮件营销的几个细节问题
			
其实说起EDM邮件营销很多做过的人都知道,目前国内邮件营销的效果其实是比较差的,为什么?因为国内没有多少使用邮件的习惯,如果不是工作所需估计很多的人都几天不碰邮件了,但是反观国外 邮件是其日常的一部分 ...
 - cwRsync window下的跨服务器的文件同步
			
cwRsync 是window下的文件同步软件,可以跨服务器运行,第一次运行的时候是全部备份同步,之后的同步采用的是增量同步 这个软件分为服务端和客户端. 服务器是需要同步的文件源, 客户端相当于是备 ...
 - windows环境下配置php和redis
			
Redis 是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库. 一.Window 下安装 下载地址:https://github.com/dmajkic/redis/downl ...
 - [原]运行编译好的Android模拟器
			
Android源码编译好了之后,我们就可以运行它了. 1.配置环境变量: /data/data/Android$ export PATH=$PATH:$(pwd)/out/host/linux-x86 ...
 - 使用docker搭建nfs实现容器间共享文件
			
首先介绍下今天的两个主角:nfs和docker nfs 是什么 NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TC ...
 - Into concurrent LRU caching once again
			
But this time, with a more product oriented point of view, instead of researching. http://openmymind ...
 - Apache+tomcat+mod_jk+centos6.2负载均衡集群配置--转载
			
转载地址:http://blog.163.com/chenhui_java/blog/static/17267249420128101191860/ 注: 由于长期受转载毒害,所以本人日志均是原创:其 ...
 - LeetCode——Find the Duplicate Number
			
Description: Given an array nums containing n + 1 integers where each integer is between 1 and n (in ...
 - Android学习笔记之横向二级菜单实现
			
PS:元旦来一发. 学习内容: 1.Android二级横向菜单的实现过程.效果如上图... 这种横向的二级菜单在很多的app都有所应用.效果看起来还是非常的美观的.也算是项目需要,自己也就学了一下 ...