您的位置:首页 > 移动开发 > Swift

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

总结:
可把嵌套函数理解为外围函数定义的局部对象,因此两次返回的嵌套函数指向的不是同一个函数对象,它们相互独立,互不影响
嵌套函数捕获外围函数对象(参数对象和局部对象)理解为嵌套函数保存了指向这些对象的引用,嵌套函数被调用时才获取这些对象值
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: