Swift 闭包简单使用

Swift开发文档中是这样介绍闭包的:闭包是可以在你的代码中被传递和引用的功能性独立模块。

闭包的形式

全局函数嵌套函数闭包表达式
有名字但不能捕获任何值。有名字,也能捕获封闭函数内的值。无名闭包,使用轻量级语法,可以根据上下文环境捕获值。

Swift中的闭包有很多优化的地方

  1. 根据上下文推断参数和返回值类型

  2. 从单行表达式闭包中隐式返回(也就是闭包体只有一行代码,可以省略return)

  3. 可以使用简化参数名,如$0, $1(从0开始,表示第i个参数…)

  4. 提供了尾随闭包语法(Trailing closure syntax)

  5. 闭包是引用类型:无论你将函数或闭包赋值给一个常量还是变量,你实际上都是将常量或变量的值设置为对应函数或闭包的引用

创建基本的闭包

let bibao = {
  print("我要创建闭包")
}

上面的代码实际上创建了一个匿名的函数,并将这个函数赋给了 driving。之后你就可以把 driving() 当作一个常规的函数来用,就像这样:

bibao()

在闭包中接收参数

当你创建闭包的时候,它们并没有名字,也没有提供书写参数的地方。但这并不意味着它们不能接收参数,只不过它们接收参数的方式稍有不同:这些参数是被写在 花括号里面的。

为了让一个闭包接收参数,你需要在花括号之后把这些参数列出来,然后跟上一个 in 关键字。这样就告诉Swift,闭包的主体是从哪里开始的。

举个例子,我们来创建一个闭包,接收一个叫 place 的字符串作为唯一的参数,就像这样:

let bibao= { (bao1: String) in
  print("我要创建 \(bao1)。")
}

函数和闭包的一个区别是运行闭包的时候你不会用到参数标签。因此,调用 driving() 的时候,我们是这样写的:

bibao("闭包")

从闭包中返回值

闭包也能返回值,写法和闭包的参数类似:写在闭包内部, in 关键字前面。

还是以 driving() 闭包为例, 让它返回一个字符串。原来的函数是这样的:

let bibao= { (bao1: String) in
  print("我要创建  \(bao1)。")
}

改成返回字符串而不是直接打印那个字符串,需要 in 之前添加 -> String,然后像常规函数那样用到 return 关键字:

let drivingWithReturn = { (bao1: String) -> String in
  return "我要创建 \(bao1)。"
}

现在我们运行这个闭包并且打印出它的返回值:

let message = drivingWithReturn("闭包")
print(message)

闭包作为参数

既然闭包可以像字符串和整数一样使用,你就可以将它们传入函数。闭包作为参数的语法乍一看一看挺伤脑筋的,让我们慢慢来。

首先,还是基本的 driving() 闭包。

let driving = {
  print("我正在创建")
}

如果我们打算把这个闭包传入一个函数,以便函数内部可以运行这个闭包。我们需要把函数的参数类型指定为 () -> Void。 它的意思是“不接收参数,并且返回 Void”。在Swift中,Void是什么也没有的意思。

好了,让我们来写一个 travel() 函数,接收不同类型的 traveling 动作, 并且在动作前后分别打印信息:

func travel(action: () -> Void) {
  print("我准备创建")
  action()
  print("我建好了")
}

现在可以用上 driving 闭包了,就像这样:

travel(action: driving)

尾随闭包语法

如果一个函数的最后一个参数是闭包,Swift允许你采用一种被称为 “拖尾闭包语法” 的方式来调用这个闭包。你可以把闭包传入函数之后的花括号里,而不必像传入参数那样。

又用到我们的 travel() 函数了。它接收一个 action 闭包。闭包在两个 print() 调用之间执行:

func travel(action: () -> Void) {
  print("我准备创建")
  action()
  print("我建好了")
}

由于函数的最后一个参数是闭包,我们可以用拖尾闭包语法来调用 travel() 函数,就像这样:

travel() {
  print("我要创建闭包")
}

实际上,由于函数没有别的参数了,我们还可以将圆括号完全移除:

travel {
  print("我要创建闭包")
}

拖尾闭包语法在Swift中非常常见,所以要加深印象。

值捕获

闭包可以在其被定义的上下文中捕获常量或变量。即使定义这些常量和变量的原作用域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
Swift 中,可以捕获值的闭包的最简单形式是嵌套函数,也就是定义在其他函数的函数体内的函数。嵌套函数可以捕获其外部函数所有的参数以及定义的常量和变量。
官方文档例子:

 func makeIncrementer(forIncrement amount: Int) -> () -> Int {
     var runningTotal = 0
     func incrementer() -> Int {
         runningTotal += amount
        return runningTotal
     }
     return incrementer
 }
 //运行结果:
 let one = makeIncrementer(forIncrement: 10)
print(one())  //10
print(one())  //20

let two = makeIncrementer(forIncrement: 10)
print(two())  //10
print(two())  //20

逃逸闭包

当一个闭包作为参数传到一个函数中,但是这个闭包在函数返回之后才被执行,我们称该闭包从函数中逃逸。当你定义接受闭包作为参数的函数时,你可以在参数名之前标注 @escaping,用来指明这个闭包是允许“逃逸”出这个函数的。(默认值:@noescaping)
官方文档例子:

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

如上面例子,加入标注@escaping即可表明这个闭包是允许逃逸的

以上就是我对Swift闭包的浅薄认知,如果有细节错误请指出,也可以查阅官方文档,链接在下面教程更为详细。
就是这样啦,爱你们么么么~~
这里是文档~
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值