Swift详解之四-------妈妈再也不用担心我的闭包了
妈妈再也不用担心我的闭包了
swift中闭包是一个很强大的东西,闭包是自包含的函数代码块,可以在代码中被传递和使用。跟C 和 Objective-C 中的代码块(blocks)很相似 。这个大家必须掌握!必须掌握!必须掌握! 闭包可以捕获和存储其所在上下文中任意常量和变量的引用。 这就是所谓的闭合并包裹着这些常量和变量,俗称闭包。下面我们就来攻克它! 1、闭包函数官方在讲解闭包函数的时候一般都是使用一个 let names = ["Chris","Alex","Ewa","Barry","Daniella"]
func backwards(s1: String,s2: String) -> Bool {
return s1 > s2
}
这里我们定义了一个 然后我们来了解下 所以 ,我们这个函数的意思就是如果第一个比第二个参数大就返回true(s1>s2),所以是一个降序的排列 ,这里得到的结果是 : 大家看着官方的 func mySort (var arr:[String],sortStr:(String,String)->Bool)->[String]
{
if(arr.count == 0){ return arr; }
let count = arr.count
var temp = ""
for i in 0..<count
{
for j in i+1..<count
{
if(!sortStr(arr[i],arr[j]))
{
temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
}
}
return arr;
}
者其实就是一个简单的冒泡排序 ,只不过把规则交给调用者 。 下面的实例我们就用自己的sort 来讲,代码都在这里。大家可以看得明白 。 这里需要补充一个知识点。 区间运算 :0...n 表示0-n的闭合区间 0..<n 表示一个包含0 不包含n半开半闭
2、闭包表达式语法然而这是一个相当冗长的方式,本质上只是写了一个单表达式函数 (a > b),但是我们还要写一个函数 ? 当然不需要,下面我们用闭合表达式语法可以更好的构造一个内联排序闭包 闭包表达式语法有如下一般形式:
{ (parameters) -> returnType in
statements
}
闭包表达式语法可以使用常量、变量和inout类型作为参数,不提供默认值。 也可以在参数列表的最后使用可变参数。 元组也可以作为参数和返回值。 let arr1 = mySort( (names),sortStr: { (s1:String,s2:String) -> Bool in return s1>s2 })
这里我们把上面传入函数的地方,我们传入了一个闭包。这里就不做过多解释。完全按照上面的语法类型
因为我们写的 所以我们的可以这样写 : let arr2 = mySort( (names),sortStr: { s1,s2 in return s1>s2 })
看到没,智能的swift帮我们把闭包缩短了很多
单行表达式闭包可以通过隐藏return关键字来隐式返回单行表达式的结果,我们这里是单行表达式 。 let arr3 = mySort( (names),s2 in s1>s2 })
我们的代码又短了很多
这时候我们的闭包就变成了下面这样 let arr4 = mySort( (names),sortStr: { $0>$1 })
哇!太厉害了,swift太强大了,你以为这是终极目标了,错了 还有更厉害的
Swift 的String类型定义了关于大于号 (>) 的字符串实现,其作为一个函数接受两个String类型的参数并返回Bool类型的值 let arr5 = mySort( (names),sortStr: > )
print(arr5) //[Ewa,Alex]
尾随闭包是一个书写在函数括号之后的闭包表达式,函数支持将其作为最后一个参数调用。 let arr6 = mySort(names) { $0>$1 }
当闭包非常长以至于不能在一行中进行书写时,尾随闭包变得非常有用。这中方式也是我们经常时候的方式 3、捕获值闭包可以在其定义的上下文中捕获常量或变量。 即使定义这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。 看到这段话是不是很晕呀,哈哈我们来看一个实例你就理解了 。 func makeRunStep(step:Int)->()->Int
{
var total = 0;
// func run()->Int {
// total+=step ;
// return total;
// }
return {()-> Int in total+=step ;
return total; }
}
这里我们定义了一个函数,传入一个 let ten = makeRunStep(10);
这里传入一个10 ,并把返回的函数类型赋值给一个常量ten 。 当我们再去执行 所以得到的结果是 :20 let ten = makeRunStep(10);
ten() //10
ten() //20
ten() //30
ten() //40
let ten2 = makeRunStep(10);
ten2() //10
如果重新调用 let seven = makeRunStep(7);
seven() //7
seven() //14
seven() //21
seven() //28
大家看到这几组数据大概明白什么意思了吧, 其实真正的原因是闭包是一个引用类型的 , let ten = makeRunStep(10);
ten() //10
ten() //20
ten() //30
ten() //40
let ten1 = ten
ten1() //50
print(ten1()) //60
两个不同的常量可以同时引用一个闭包 。 关于闭包大致就这么多。如有疑问可以相互交流学习 。希望共同进步! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |