Swift入门教程系列6-闭包
来源:互联网 发布:安卓博德之门2修改数据 编辑:程序博客网 时间:2024/05/01 19:17
闭包
闭包是什么,如果你接触过Objective C,那么闭包类似于其中的block
闭包是一种自包含的函数代码块,可以被传递和使用(简单理解就是一种简化了的函数类型)
闭包可以捕获和存储上下文的任意常量和变量的引用,注意是引用
swfit鼓励使用闭包,因为其小巧,简洁。
闭包表达式
{
(参数1,参数2,...)->返回值类型 in
执行语句
}
闭包表达式以其小巧的特点,经常用作函数的参数:当一个函数需要另一个函数作为参数的时候,闭包能够很好地简化代码量,增加代码的灵活性。
通过闭包的定义可以看出,全局函数和嵌套函数是特殊的闭包
sort 和sorted
两个函数都可以对数组排序
差别是,sort函数传入引用,直接对传入的数据进行操作。sorted函数传入值,返回排序好的数组
官方文档里采用sorted函数的讲解非常直白透彻,本文采用相似代码来讲解,最后通过GCD,和UIView.animateWithDuration两个使用情景来讲解闭包的使用
通过上述sort的说明可以看出,sort函数需要一个(T,T)->Bool类型的闭包函数
这里T类似于C++的模板,表示类型
如果我们定义一个
var array = [1,3,4,2],如果我们想要对其使用sort
则需要的闭包函数类型为(Int,Int)->Bool
一 从一个例子理解闭包
1、使用函数类型
定义一个函数
初始的方法代码量很大,很复杂,所以,接下来一步步简化
2、使用闭包表达式
3、闭包表达式类型推断
因为sort函数这样定义
闭包表达式的两个参数类型都是Int,至于返回值一定是Bool,因为编译器有如此猜测,我们可以这么写
4、单表达式隐式返回
由于上述闭包的表达式只有return lhs < rhs
所以,及时省略return也不会产生歧义,编译器会推断这一行的执行结果作为返回值
5、参数名称缩写
如果你熟悉shell或者一些脚本语言,那么你肯定知道其中$0代表第一个变量,$1代表第二个变量
在swift的闭包表达式中也是如此
swift中用$0表示第一个变量 $n表示第n个变量
这里$0代表上述的lhs,$1代表rhs
所以,干脆连参数表达式和in我们也省略了
6、运算符函数
和C++的运算符重载类似,因为swift本身支持模板,所以运算符本身也是一个函数
由于<运算符支持(Int,Int)->Bool,所以上述可以更加简写为
二、闭包表达式尾随
一中的例子闭包比较简单,所以我们一步步简化。当闭包的表达式比较复杂的时候怎么办呢?
当闭包作为参数中的最后一个参数时,闭包表达式可以用尾随的方式
上边的例子可以改为
当只有闭包一个参数的时候,()可以省略
onlyOne{
//闭包表达式定义
}
这里,我举个实例,帮助大家复习之前学过的内容,顺便更加深入的理解闭包
由于只有一个闭包参数,所以调用的时候省略了()
我这里闭包的定义为,输出myname + " hwc",并且打印
看到这里,不难看出,当闭包作为参数的时候,实际上给用户提供了一个接口,我定义好我规则里的东西,就像我告诉你早上九点上班,晚上六点下班,这是规则里的事情,而晚上六点到早上九点就是我暴露给你的接口,你想干嘛我不管
三、闭包捕获值
就是闭包可以捕获上下文的变量和常量,典型的例子是嵌套函数
在举个例子
我们如下使用
四、闭包和函数类型都是引用
或者干脆用$0来代表是否成功,不过,个人不太喜欢这种写法
闭包是什么,如果你接触过Objective C,那么闭包类似于其中的block
闭包是一种自包含的函数代码块,可以被传递和使用(简单理解就是一种简化了的函数类型)
闭包可以捕获和存储上下文的任意常量和变量的引用,注意是引用
swfit鼓励使用闭包,因为其小巧,简洁。
闭包表达式
{
(参数1,参数2,...)->返回值类型 in
执行语句
}
闭包表达式以其小巧的特点,经常用作函数的参数:当一个函数需要另一个函数作为参数的时候,闭包能够很好地简化代码量,增加代码的灵活性。
通过闭包的定义可以看出,全局函数和嵌套函数是特殊的闭包
- 全局函数是一个不会捕获任何值的闭包
- 嵌套函数是一个有名字并且可以捕获其封闭函数域内值得闭包
- 闭包表达式是一个可以捕获上下文中常量或者变量值得闭包
sort 和sorted
sort(&array[T],isOrderdBefore:(T,T)->Bool)[C.Generator.Element] sorted(source C,isOrderdBefore(C.Generator.Element,C.Generator.Element)->Bool)
两个函数都可以对数组排序
差别是,sort函数传入引用,直接对传入的数据进行操作。sorted函数传入值,返回排序好的数组
官方文档里采用sorted函数的讲解非常直白透彻,本文采用相似代码来讲解,最后通过GCD,和UIView.animateWithDuration两个使用情景来讲解闭包的使用
通过上述sort的说明可以看出,sort函数需要一个(T,T)->Bool类型的闭包函数
这里T类似于C++的模板,表示类型
如果我们定义一个
var array = [1,3,4,2],如果我们想要对其使用sort
则需要的闭包函数类型为(Int,Int)->Bool
一 从一个例子理解闭包
1、使用函数类型
定义一个函数
func status(lhs:Int,rhs:Int)->Bool{ return lhs < rhs }sort(&array,status)array.description这里,我们传入一个函数类型
初始的方法代码量很大,很复杂,所以,接下来一步步简化
2、使用闭包表达式
sort(&array,{(lhs:Int,rhs:Int)->Bool in return lhs < rhs})array.description这里我们使用到了闭包
{(rhs:Int,rhs:Int)->Bool in return lhs < rhs}
3、闭包表达式类型推断
因为sort函数这样定义
sort(&array[T],isOrderdBefore:(T,T)->Bool)所以,编译器可以猜出闭包表达式中的类型是和数组的类型一致的,也就是说,在本文的例子中
闭包表达式的两个参数类型都是Int,至于返回值一定是Bool,因为编译器有如此猜测,我们可以这么写
sort(&array,{lhs,rhs in return lhs < rhs})
4、单表达式隐式返回
由于上述闭包的表达式只有return lhs < rhs
所以,及时省略return也不会产生歧义,编译器会推断这一行的执行结果作为返回值
sort(&array,{lhs,rhs in lhs < rhs})
5、参数名称缩写
如果你熟悉shell或者一些脚本语言,那么你肯定知道其中$0代表第一个变量,$1代表第二个变量
在swift的闭包表达式中也是如此
swift中用$0表示第一个变量 $n表示第n个变量
这里$0代表上述的lhs,$1代表rhs
所以,干脆连参数表达式和in我们也省略了
sort(&array,{$0 < $1})
6、运算符函数
和C++的运算符重载类似,因为swift本身支持模板,所以运算符本身也是一个函数
由于<运算符支持(Int,Int)->Bool,所以上述可以更加简写为
sort(&array,<)
二、闭包表达式尾随
一中的例子闭包比较简单,所以我们一步步简化。当闭包的表达式比较复杂的时候怎么办呢?
当闭包作为参数中的最后一个参数时,闭包表达式可以用尾随的方式
上边的例子可以改为
sort(&array){$0 < $1}
当只有闭包一个参数的时候,()可以省略
onlyOne{
//闭包表达式定义
}
这里,我举个实例,帮助大家复习之前学过的内容,顺便更加深入的理解闭包
class CSND{ lazy var myname = "hwc" func myprint(method:(input:String)->()){ method(input:"hello") }}var object = CSND()object.myprint{ var result = $0 + " hwc" println(result)}这里myprint的参数唯一,并且只是一个函数类型,所以我们可以传入闭包表达式
由于只有一个闭包参数,所以调用的时候省略了()
我这里闭包的定义为,输出myname + " hwc",并且打印
看到这里,不难看出,当闭包作为参数的时候,实际上给用户提供了一个接口,我定义好我规则里的东西,就像我告诉你早上九点上班,晚上六点下班,这是规则里的事情,而晚上六点到早上九点就是我暴露给你的接口,你想干嘛我不管
三、闭包捕获值
就是闭包可以捕获上下文的变量和常量,典型的例子是嵌套函数
func method(){ var temp = 10 func addOne(){temp = temp + 1 } addOne() addOne() println(temp)}可以看到最后打印的值是12,也就是说,每次捕获到addOne函数中的temp是引用,而不是副本
在举个例子
func CreateMethod()->(Int)->(Int){ var result = 0 func toReturnMethod(input:Int)->(Int){ result = result + input return result }}函数CreateMethod创造一个函数,(Int)->(Int)这个函数捕获result,然后加上input,后返回
我们如下使用
var function = CreateMethod()var result = function(input:10)result = function(input:10)result = function(input:10)
最后result = 30
说明swift仍然替我们保存了我们想要的那个局部变量result
四、闭包和函数类型都是引用
func CreateMethod()->(Int)->(Int){ var result = 0 func toReturnMethod(input:Int)->(Int){ return result + 5 } return toReturnMethod}
var function1 = CrethodMethod()var function2 = function1
//这里 function1和function2都是闭包类型,他们指向同一块内存
五、GCD与UIView实例
UIView.animateWithDuration(1.0,animations:{ //动作},completion:{status in //status代表动作是否成功 //动作结束后的执行})也可以这么写UIView.animateWithDuration(1.0,animations:{ //动作}){status in //status代表动作是否成功 //动作结束后的执行}
或者干脆用$0来代表是否成功,不过,个人不太喜欢这种写法
GCD的例子太多了,用之前写过的单例作为例子
关于swift中GCD的的使用,会在下周更新教程
class hwcSingleton { var testVariable:Int! func print(){testVariable = testVariable + 1println(testVariable)} class var sharedObject: hwcSingleton { struct StaticStruct { static var predicate : dispatch_once_t = 0 static var instance : hwcSingleton? = nil } dispatch_once(&StaticStruct.predicate) { StaticStruct.instance = hwcSingleton() StaticStruct.instance?.testVariable = 10 } return StaticStruct.instance! }}g
17 0
- Swift入门教程系列6-闭包
- Swift学习笔记系列——(6)闭包
- Swift入门教程系列8-枚举
- Swift系列之闭包(Closure)
- swift入门教程系列7-控制流
- Swift入门教程系列5-函数+selector在swift中的用法
- Swift傻傻分不清楚系列(九)闭包
- 【Swift初见】Swift闭包
- Swift 入门教程
- Swift入门教程
- Swift官方入门教程系列--四--自定义控件【翻译版,源代码】
- swift学习笔记6 闭包
- Swift 闭包(六)
- Swift之闭包
- swift closure 闭包
- swift,闭包
- Swift闭包表达式
- [Swift]闭包
- uva562(DP)
- 机器学习学习,笔记及感想1
- 【C#网络编程系列】专题三:自定义web服务器
- 通过/dev/mem只能访问high_memory高端内存以下的内核线性地址空间
- STL 型别技术
- Swift入门教程系列6-闭包
- springmvc为什么要和spring整合
- C语言二维数组
- 黑马程序员:OC学习日记之self
- HDU 4565So Easy! 共轭构造+矩阵快速幂
- Codeforces Round #274 (Div. 2) c Exams
- 【数学:卡特兰数】总结
- eclipse 注释掉代码,取消代码注释
- Spring注解形式的定时任务配置详解(转)