- 捕获值
- 闭包可以在其定义的上下文中捕获常量或变量
- 即使定义这些常量和变量的原域已经不存在,闭包仍然可以在闭包函数体内引用和修改这些值。
- Swift最简单的闭包形式是嵌套函数,也就是定义在其他函数的函数体内的函数
- 嵌套函数可以捕获其外部函数所有的参数以及定义的常量和变量。
- 看这个例子:
func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor }
- 一个函数makeIncrementor ,它有一个Int型的参数amout, 并且它有一个外部参数名字forIncremet,意味着你调用的时候,必须使用这个外部名字。返回值是一个()-> Int的函数。
- 函数题内,声明了变量runningTotal 和一个函数incrementor。
- incrementor函数并没有获取任何参数,但是在函数体内访问了runningTotal和amount变量。这是因为其通过捕获在包含它的函数体内已经存在的runningTotal和amount变量而实现。
- 由于没有修改amount变量,incrementor实际上捕获并存储了该变量的一个副本,而该副本随着incrementor一同被存储。
- 所以我们调用这个函数时会累加:
import Cocoa func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) // 返回的值为10 print(incrementByTen()) // 返回的值为20 print(incrementByTen()) // 返回的值为30 print(incrementByTen())
- 以上程序执行输出结果为:
10 20 30
- 闭包是引用类型
- 上面的例子中,incrementByTen是常量,但是这些常量指向的闭包仍然可以增加其捕获的变量值。
- 这是因为函数和闭包都是引用类型。
- 无论您将函数/闭包赋值给一个常量还是变量,您实际上都是将常量/变量的值设置为对应函数/闭包的引用。 上面的例子中,incrementByTen指向闭包的引用是一个常量,而并非闭包内容本身。
- 这也意味着如果您将闭包赋值给了两个不同的常量/变量,两个值都会指向同一个闭包:
import Cocoa func makeIncrementor(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementor() -> Int { runningTotal += amount return runningTotal } return incrementor } let incrementByTen = makeIncrementor(forIncrement: 10) // 返回的值为10 incrementByTen() // 返回的值为20 incrementByTen() // 返回的值为30 incrementByTen() // 返回的值为40 incrementByTen() let alsoIncrementByTen = incrementByTen // 返回的值也为50 print(alsoIncrementByTen())
- 以上程序执行输出结果为:
50
swfit Block 捕获值 与 闭包是引用类型
最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
推荐阅读更多精彩内容
- 本章将会介绍 闭包表达式尾随闭包值捕获闭包是引用类型逃逸闭包自动闭包枚举语法使用Switch语句匹配枚举值关联值原...