Swift学习笔记(7)—— 闭包

作为一个JAVA程序员,之前对闭包几乎没接触。(嗯,JAVA7开始支持闭包了,BUT So What?)
乍一看这个概念还挺绕。


7.闭包

Swift中闭包的定义,包括如下三种——
1. 全局函数
2. 嵌套函数
3. 闭包表达式
暂且把闭包理解为一个匿名函数吧~?

闭包表达式

基本语法

{ (parameters) -> returnType in
    statements
}
//或者语句较短时可以放到一行
{ (参数表) -> 返回类型 in statements }

//一个例子: sort函数的第二个参数是一个闭包
reversed = sort(names, { (s1: String, s2: String) -> Bool in
    return s1 > s2
})

类型推导

类型推导在Swift中的用处很多,这里又是一个体现。
可以根据上下文推断闭包的参数类型和返回类型。

//上面的闭包可以简写成:
{(s1,s2) in return  s1 > s2}

单表达式隐式返回

表达式只有一行的时候可以省略return

//省略 return
{ (s1,s2) in s1 > s2 }
//调用
sort(naems,{  (s1,s2) in s1 > s2 })

参数名称缩写

可以直接用 $0,$1等…来调用参数。

//使用参数名称缩写
{ ($0 > $1) }
//调用
sort(naems,{ ($0 > $1) })

运算符函数

因为>运算符本身就是一个(String,String)->Int的符号函数。
所以这里可以直接用>作为参数传入到sort函数。

// 简称成 >
sort(names,>)

我只能说:太!凶!残!了!

尾随闭包

当闭包作为一个函数的最后一个参数时,可以使用尾随闭包的形式。

// 以下是不使用尾随闭包进行函数调用
someFunctionThatTakesAClosure({
    // 闭包主体部分
})

// 以下是使用尾随闭包进行函数调用
someFunctionThatTakesAClosure() {
    // 闭包主体部分
}

嗯?好像就是把半个小括号提前了? o(╯□╰)o
这么做的好处是——据说可以让代码更简洁。

当只有一个闭包做参数时,可以把小括号省略掉

捕获值

闭包可以捕获上下文中的中常量或变量,被捕获的常量或变量即使在原来的域中不再存在,在闭包中仍可以使用和修改它。
捕获这个词用的真生动啊!
举个栗子:

//定义一个返回类型为 ()-> Int 类型函数
func makeIncrementor(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementor() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementor
}

//fun1被赋值为:一个每次调用都会增加3的 ()->Int 函数
var fun1 = makeIncrementor(forIncrement: 3)
fun1()// 值为 3
fun1()// 值为 6

在这个例子中:
incrementor是一个内嵌函数,即一个闭包。
捕获了外部的runningTotal变量,并且即使外部的runningTotal被销毁,闭包内仍能保持和使用它(每次让丫增加3)。

闭包是引用类型

就是指针的意思喽?
即使用一个把一个闭包赋值给一个常量,闭包本身的内容仍然是可以修改的。



这笔记只是给我自己看的,用以标记一些我觉得需要记的或者有意思的一些知识点,有很多我觉得没必须要赘述的东西就没记,所以是不系统的,只作提示用。
感谢 numbbbbb以及其他贡献者: https://github.com/numbbbbb/the-swift-programming-language-in-chinese
当然,还有英文页: https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/BasicOperators.html#//apple_ref/doc/uid/TP40014097-CH6-XID_70


http://www.barryzhang.com/archives/246

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*