swift——复合类型——函数——闭包
2017-05-18 16:48
260 查看
闭包
闭包,closure,类似于oc中block及其他语言中lambda闭包三种形式:
全局函数:有名字,不捕获值
嵌套函数:有名字,从外围函数捕获值
闭包表达式:无名字,从上下文捕获值
闭包表达式
嵌套函数
func compare(a: Int, _ b: Int, _ cmp: (Int, Int) -> Bool) -> Int { return cmp(a, b) ? a : b } func use_compare() { func cmp(a: Int, b: Int) -> Bool { return a > b } let result = compare(8, 5, cmp) print("result = \(result)") }
完整闭包表达式
func compare(a: Int, _ b: Int, _ cmp: (Int, Int) -> Bool) -> Int { return cmp(a, b) ? a : b } func use_compare() { let result = compare(8, 5, { (a: Int, b: Int) -> Bool in return a > b }) print("result = \(result)") }
总结:
完整闭包表达式包括参数类型,参数名,返回类型,函数体(以in起始),闭包表达式包括在{}中,与嵌套函数相比,omit了函数名和argument label
let cmp: (Int, Int) -> Bool = { (a: Int, b: Int) -> Bool in return a > b }是合法的,只要参数类型和返回类型一致,显然闭包表达式类型为函数类型
类型推断
func compare(a: Int, _ b: Int, _ cmp: (Int, Int) -> Bool) -> Int { return cmp(a, b) ? a : b } func use_compare() { let result = compare(8, 5, { a, b in return a > b }) print("result = \(result)") }
总结:
闭包表达式赋值给函数类型时,可omit参数类型以及返回类型,进一步可omit包围参数名的圆括号,因为可从函数类型推断出闭包表达式参数类型和返回类型
let cmp: (Int, Int) -> Bool = { a, b in return a > b }是合法的,可从左值函数类型推断出右值闭包表达式参数类型和返回类型
隐式return
func compare(a: Int, _ b: Int, _ cmp: (Int, Int) -> Bool) -> Int { return cmp(a, b) ? a : b } func use_compare() { let result = compare(8, 5, { a, b in a > b }) print("result = \(result)") }
总结:
只有唯一一条表达式的闭包表达式可omit return,闭包表达式把唯一一条表达式值作为闭包表达式返回值隐式返回
let cmp: (Int, Int) -> Bool = { a, b in a > b }是合法的,唯一一条表达式值作为闭包表达式返回值隐式返回
形参速记
func compare(a: Int, _ b: Int, _ cmp: (Int, Int) -> Bool) -> Int { return cmp(a, b) ? a : b } func use_compare() { let result = compare(8, 5, { $0 > $1 }) print("result = \(result)") }
总结:
可进一步omit形参名(包括in),使用形参速记$0,$1等,从0起始
let cmp: (Int, Int) -> Bool = { $0 > $1 }
操作符重载
func compare(a: Int, _ b: Int, _ cmp: (Int, Int) -> Bool) -> Int { return cmp(a, b) ? a : b } func use_compare() { let result = compare(8, 5, >) print("result = \(result)") }
总结:
如果参数类型支持相应的操作符重载,可omit参数,只保留重载的操作符
let cmp: (Int, Int) -> Bool = >非法
拖尾闭包
func compare(a: Int, _ b: Int, cmp: (Int, Int) -> Bool) -> Int { return cmp(a, b) ? a : b } func use_compare() { let result = compare(8, 5) { (a: Int, b: Int) -> Bool in return a > b } print("result = \(result)") }
总结:
如果最后一个参数是函数类型(包括只有一个参数),实参使用闭包表达式传时,可直接把闭包表达式写在函数调用后面,并且可omit该参数argument label,当闭包表达式比较长时使用拖尾闭包增强代码可读性
捕获值
嵌套函数捕获
func makeIncrementer(forIncrement amount: Int) -> () -> Int { var runningTotal = 0 func incrementer() -> Int { runningTotal += amount return runningTotal } return incrementer } func nestedFuncCapture() { let incrementBy5 = makeIncrementer(forIncrement: 5) let incrementBy8 = makeIncrementer(forIncrement: 8); print(incrementBy5()) print(incrementBy5()) print(incrementBy5()) print(incrementBy8()) print(incrementBy8()) print(incrementBy8()) }
output:
5 10 15 8 16 24
总结:
可把嵌套函数理解为外围函数定义的局部对象,因此两次返回的嵌套函数指向的不是同一个函数对象,它们相互独立,互不影响
嵌套函数捕获外围函数对象(参数对象和局部对象)理解为嵌套函数保存了指向这些对象的引用,嵌套函数被调用时才获取这些对象值
相关文章推荐
- Swift 学习笔记 [1] 类型 值 集合 函数 闭包
- swift——复合类型——函数——函数类型
- 浅谈swift中的函数类型和闭包
- swift——复合类型——函数——参数 返回类型
- Swift基础语法: 23 - Swift的闭包简介, Sorted函数, 闭包的表达式语法, 根据上下文推断类型, 参数名简写, 运算符函数
- Swift 1.1语言第7章 函数和闭包
- swift中的函数用法,嵌套函数和返回一个函数以及函数作为参数,闭包
- Swift笔记(五)之函数与闭包(Functions and Closures)
- Swift入门篇-闭包和函数
- Swift 基础语法三--函数和闭包
- Swift 1.1语言第7章 函数和闭包
- Swift之函数和闭包
- Python函数小结(1)--参数类型(*, ** 的区别), 闭包
- Swift函数类型
- Swift函数闭包
- swift 学习(二)基础知识 (函数,闭包,ARC,柯里化,反射)
- 苹果新的编程语言 Swift 语言进阶(六)--函数和闭包
- Swift函数和闭包
- Swift学习笔记 - 函数与闭包
- Swift 中的利刃,函数和闭包