Swift基础语法: 23 - Swift的Trailing闭包, 捕获, 闭包是引用类型

Swift基础语法: 23 - Swift的Trailing闭包, 捕获, 闭包是引用类型,第1张

概述前面我们基本上了解了Swift的闭包简介, 现在让我们来继续讲解闭包的其他内容: 1.Trailing闭包 在前面我们知道了简单的闭包是怎么样运用的, 但在实际开发中, 我们不可能只使用简单的闭包, 所以这时候就出现了第二种闭包的写法, 那就是Trailing闭包, 让我们来看看例子: let digitNames = [ 0: "Zero", 1: "One", 2: "Two", 3:

前面我们基本上了解了Swift的闭包简介,现在让我们来继续讲解闭包的其他内容:

1.Trailing闭包

在前面我们知道了简单的闭包是怎么样运用的,但在实际开发中,我们不可能只使用简单的闭包,所以这时候就出现了第二种闭包的写法,那就是Trailing闭包,让我们来看看例子:

let digitnames = [    0: "Zero",1: "One",2: "Two",3: "Three",4: "Four",5: "Five",6: "Six",7: "Seven",8: "Eight",9: "Nine"]let numbers = [16,58,510]let strings = numbers.map {    (var number) -> String in    var output = ""    while number > 0 {        output = digitnames[number % 10]! + output        number /= 10    }    return output}println(strings)// 打印出来的结果: [Onesix,FiveEight,FiveOneZero]

PS:
1.在这个例子中,strings 常量被推断为字符串类型数组,即 [String],map 在数组中为每一个元素调用了闭包表达式,您不需要指定闭包的输入参数 number 的类型,因为可以通过要映射的数组类型进行推断,闭包表达式在每次被调用的时候创建了一个字符串并返回。其使用求余运算符 (number %10) 计算最后一位数字并利用 digitnames 字典获取所映射的字符串.

2.字典 digitnames 下标后跟着一个叹号 (!),因为字典下标返回一个可选值 (optional value),表明即使该 key 不存在也不会查找失败,在上例中,它保证了 number % 10 可以总是作为一个 digitnames 字典的有效下标 key,因此叹号可以用于强展开 (force-unwrap) 存储在可选下标项中的 String 类型值.

2.捕获

在我们使用闭包的时候,其实我们还可以捕获我们自己定义的常量或者变量,即使里面的常量和变量的作用域不存在,闭包仍然可以在闭包函数体内引用或者修改,Swift 最简单的闭包形式是嵌套函数,也就是定义在其他函数体内的函数,嵌套函数可以捕 获其外部函数所有的参数以及定义的常量和变量,让我们一起来看看:

func makeIncrementor(forIncrement amount: Int) -> () -> Int {    var runningTotal = 0    func incrementor() -> Int {        runningTotal += amount        return runningTotal    }    return incrementor}let incrementBySeven = makeIncrementor(forIncrement: 7)let a = incrementBySeven()println(a)// 打印出来的结果: 7

PS:
1.makeIncrementor 返回类型为 () -> Int,这意味着其返回的是一个函数,而不是一个简单类型值,该函数在每次调用时不接受参数只返回一个 Int 类型的值,关于函数返回其他函 数的内容,请查看 Function Types as Return Types.

2.makeIncrementor 函数定义了一个整型变量 runningTotal (初始为 0) 用来存储当前增加总数,该值通过 incrementor 返回.

3.makeIncrementor 有一个 Int 类型的参数,其外部命名为 forIncrement,内部命名为 amount,表示每次 incrementor 被调用时 runningTotal 将要增加的量.

4.incrementor 函数用来执行实际的增加 *** 作,该函数简单地使 runningTotal 增加 amount,并将其返回.

5.Swift 会决定捕获引用还是拷贝值,您不需要标注 amount 或者 runningTotal 来声明在嵌入的 incrementor 函数中的使用方式,Swift 同时也处理 runingTotal 变量的内存管理 *** 作,如果不再被 incrementor 函数使用,则会被清除.

还有另外一个例子也很好玩,比如:

let incrementBySeven = makeIncrementor(forIncrement: 7)let a = incrementBySeven()let b = incrementBySeven()let c = incrementBySeven()println("\(a),\(b),\(c)")// 打印出来的结果: 7,14,21

上面已经很好的解释了,这里我就不多做解释了,还有一个注意点,21let incrementByTen = makeIncrementor(forIncrement: 10)let A = incrementByTen()let B = incrementByTen()let C = incrementByTen()println("\(A),\(B),\(C)")// 打印出来的结果: 10,20,30

虽然这两个常量调用的是同一个闭包,但是它们之间所捕获的内容并没有关联,这个需要注意.

3.闭包是引用类型


上面的例子中,incrementBySeven 和 incrementByTen 是常量,但是这些常量指向的闭包仍然可以增加其捕获的变量值. 这是因为函数和闭包都是引用类型.

无论您将函数/闭包赋值给一个常量还是变量,您实际上都是将常量/变量的值设置为对应函数/闭包的引用,上面的例子中,incrementByTen 指向闭包的引用是一个常量,而并非闭包内容本身,比如:

let alsoIncrementByTen = incrementByTen()println(alsoIncrementByTen)// 打印出来的结果: 40

好了,这次我们就讲到这里,下次我们继续~

总结

以上是内存溢出为你收集整理的Swift基础语法: 23 - Swift的Trailing闭包, 捕获, 闭包是引用类型全部内容,希望文章能够帮你解决Swift基础语法: 23 - Swift的Trailing闭包, 捕获, 闭包是引用类型所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1088605.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-27
下一篇 2022-05-27

发表评论

登录后才能评论

评论列表(0条)

保存