【Swift学习】Swift编程之旅---闭包(十一)
闭包是可以在代码中被传递和使用的自包含功能模块,它很像c和oc中的block,和.net中的lambdasbas表达式。
闭包可以捕获和存储其所在上下文中任意常量和变量的引用。 包裹着这些常量和变量的包俗称闭包。Swift会为您管理在捕获过程中涉及到的内存操作。下面是闭包的3中表现形式
- 全局函数是一个有名字但不会捕获任何值的闭包
- 嵌套函数是一个有名字并可以捕获其封闭函数域内值的闭包
- 闭包表达式是一个利用轻量级语法所写的可以捕获其上下文中变量或常量值的没有名字的闭包
Swift的闭包表达式拥有简洁的风格,并鼓励在常见场景中以实现语法优化,主要优化如下:
- 利用上下文推断参数和返回值类型
- 单表达式(single-expression)闭包可以省略 return 关键字
- 参数名称简写
- Trailing 闭包语法
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
func backwards(s1: String, _ s2: String) -> Bool {
return s1 > s2
}
var reversed = names.sort(backwards)
// reversed is equal to ["Ewa", "Daniella", "Chris", "Barry", "Alex"]

reversed = sort(names, { (s1: String, s2: String) -> Bool in
return s1 > s2
})
reversed = sort(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } )
这说明 sort 函数的整体调用保持不变,一对圆括号仍然包裹住了函数中整个参数集合。而其中一个参数现在变成了内联闭包 。
reversed = sort(names, { s1, s2 in return s1 > s2 } )
reversed = sort(names, { s1, s2 in s1 > s2 } )
reversed = sort(names, { $ > $ } )
运算符函数
reversed = sort(names, >)
func someFunctionThatTakesAClosure(closure: () -> ()) {
// 函数体部分
} // 以下是不使用 trailing 闭包进行函数调用 someFunctionThatTakesAClosure({
// 闭包主体部分
}) // 以下是使用 trailing 闭包进行函数调用 someFunctionThatTakesAClosure() {
// 闭包主体部分
}
注意:如果函数只需要闭包表达式一个参数,当您使用 trailing 闭包时,您甚至可以把 () 省略掉。
在上例中作为 sort 函数参数的字符串排序闭包可以改写为:
reversed = sort(names) { $ > $ }
let digitNames = [
: "Zero", : "One", : "Two", : "Three", : "Four",
: "Five", : "Six", : "Seven", : "Eight", : "Nine"
]
let numbers = [, , ]
let strings = numbers.map {
(var number) -> String in
var output = ""
while number > {
output = digitNames[number % ]! + output
number /=
}
return output
}
// strings 常量被推断为字符串类型数组,即 String[]
// 其值为 ["OneSix", "FiveEight", "FiveOneZero"]
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
var runningTotal =
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
return incrementor
}
func incrementor() -> Int {
runningTotal += amount
return runningTotal
}
let incrementByTen = makeIncrementor(forIncrement: )
该例子定义了一个叫做 incrementByTen 的常量,该常量指向一个每次调用会加10的 incrementor 函数。 调用这个函数多次可以得到以下结果:
incrementByTen()
// 返回的值为10
incrementByTen()
// 返回的值为20
incrementByTen()
// 返回的值为30
如果您创建了另一个 incrementor,其会有一个属于自己的独立的 runningTotal 变量的引用。 下面的例子中,incrementBySevne 捕获了一个新的 runningTotal 变量,该变量和 incrementByTen 中捕获的变量没有任何联系:
let incrementBySeven = makeIncrementor(forIncrement: )
incrementBySeven()
// 返回的值为7
incrementByTen()
// 返回的值为40
如果您闭包分配给一个类实例的属性,并且该闭包通过指向该实例或其成员来捕获了该实例,您将创建一个在闭包和实例间的强引用环。 Swift 使用捕获列表来打破这种强引用环
let alsoIncrementByTen = incrementByTen
alsoIncrementByTen()
// 返回的值为50
【Swift学习】Swift编程之旅---闭包(十一)的更多相关文章
- swift学习笔记2——函数、闭包
之前学习swift时的个人笔记,根据github:the-swift-programming-language-in-chinese学习.总结,将重要的内容提取,加以理解后整理为学习笔记,方便以后查询 ...
- Swift学习——Swift基础具体解释(一)
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zhenyu5211314/article/details/34807025 注:由于基础部分在Swi ...
- Swift学习之十四:闭包(Closures)
* 闭包(Closures) * 闭包是自包含的功能代码块,可以在代码中使用或者用来作为参数传值. * 在Swift中的闭包与C.OC中的blocks和其它编程语言(如Python)中的lambdas ...
- Swift学习(三):闭包(Closures)
定义 闭包(Closures)是独立的函数代码块,能在代码中传递及使用. 语法 {(parameters) -> return type in statements } 注:闭包表达式语法可以使 ...
- Swift学习——Swift解释特定的基础(七)
Implicitly Unwrapped Optionals 隐式解析选项 如上所述.可选意味着常数或变量"没有值".通过可选if声明来推断是否存在值,假设有值析值. 有时候 ...
- Swift学习——Swift解释具体的基础(六)
Optionals 可选 可选(它似乎并不如此翻译)它适用于那些值这种情况可能是空的,有两种情况一个可选:存在值并等于x,要么值不存在. 选配的概念在OC和C里面并没有.在OC中最接近的概念就是 ...
- Swift 学习- 08 -- 闭包
// 闭包是自包含的函数代码块, 可以在代码中被传递和使用, swift 中的闭包 与 C语言 和 OC 中的代码块 (blocks) 以及其他一些编程语言中的匿名函数比较类似 // 闭包可以捕获和存 ...
- iOS ---Swift学习与复习
swift中文网 http://www.swiftv.cn http://swifter.tips/ http://objccn.io/ http://www.swiftmi.com/code4swi ...
- ios -- 教你如何轻松学习Swift语法(三) 完结篇
前言:swift语法基础篇(二)来了,想学习swift的朋友可以拿去参考哦,有兴趣可以相互探讨,共同学习哦. 一.自动引用计数 1.自动引用计数工作机制 1.1 swift和o ...
随机推荐
- 桌面 透明 三角形 分层窗口 DX
//桌面 透明 三角形 分层窗口 DX //IDirect3DSurface9 GetDC UpdateLayeredWindow #include <Windows.h> #includ ...
- Amazon AWS EC2开启Web服务器配置
在Amazon AWS EC2申请了一年的免费使用权,安装了CentOS + Mono + Jexus环境做一个Web Server使用. 在上述系统安装好之后,把TCP 80端口开启(iptable ...
- Android setTag方法的key问题
android在设计View类时,为了能储存一些辅助信息,设计一个一个setTag/getTag的方法.这让我想起在Winform设计中每个Control同样存在一个Tag. 今天要说的是我最近学习a ...
- Unity3D热更新全书-脚本(四) 用C#LightEvil搭建实际开发使用的脚本框架
C#LightEvil之前提供了很多和Unity结合的例子,都是采用把脚本文件放置在StreamingAssets中的方法. 这样可以利用Unity的特性,放在这个目录中的CS文件会被编译器编译,我们 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(十五):消息加密
前不久,微信的企业号使用了强制的消息加密方式,随后公众号也加入了可选的消息加密选项.目前企业号和公众号的加密方式是一致的(格式会有少许差别). 加密设置 进入公众号后台的“开发者中心”,我们可以看到U ...
- Java Socket Server的演进 (一)
最近在看一些网络服务器的设计, 本文就从起源的角度介绍一下现代网络服务器处理并发连接的思路, 例子就用java提供的API. 1.单线程同步阻塞式服务器及操作系统API 此种是最简单的socket服务 ...
- knh
市场调研,分析—— 决定是否创业 不要再极度的沉默无言.宅.无存在感,无趣,难熬..
- 几款开源的图形化Redis客户端管理软件
转载于:http://www.itxuexiwang.com/a/shujukujishu/redis/2016/0216/98.html?1455870209 Redis是一个超精简的基于内存的键值 ...
- easyui combotree下拉框多选赋值
发现jquery.easyui.min.js 1.3.4版本的用setValues给多选下拉框赋值不成功,只能用1.3.1版本的 Html代码: <input id="ProductL ...
- APP 版本更新 流程(已上架APP,提交新版本)
背景: 今天发布app的新版本, 可是无奈换了电脑, 没有了以前上架时候的发布证书和描述文件. 但是没关系, 依然可以上传成功,哈哈哈~ 虽然走了很多弯路 - -|| 如果是向 App Store 提 ...