闭包表达式
重点:在swift中 可以通过 func 定义一个函数 也可以通过闭包表达式定义一个函数
例如:1、使用func 定义一个函数
func sunm(_ v1: Int, _ v2: Int) -> Int{v1 + v2}
例如:2、使用闭包表达式定义一个函数
var fn = {
(v1: Int,v2: Int) -> Int in
return v1 + v2
}
一、闭包表达式的格式
{
(参数列表) -> 返回类型 in
函数体代码
}
// 注意⚠️:
// in 前面是 参数列表和返回值
// in 后面是函数体代码
// in 主要作用就是区分 参数列表,返回值 和 函数体代码的区别
二、闭包表达式的简写
原始函数
func exec(v1:Int ,v2:Int,fn:(Int,Int) -> Int){
print(fn(v1,v2))
}
//上述函数可以简写成
exec(v1: 10, v2: 20,fn:{ (v1:Int, v2:Int) in
return v1 + v2
})
//还可以简写成
exec(v1: 10, v2: 20,fn: {
(v1,v2) in return v1 + v2
})
//还可以简写成
exec(v1: 10, v2: 20,fn: {
(v1,v2) in v1 + v2
})
//还可以简写成
// $0 代表最前面的参数 $1 代表第二个 以此类推
// 这个地方 因为参数都省略了 所以 in 也可以省略
exec(v1: 10, v2: 20,fn: {$0 + $1})
//还可以简写成
//编译器很智能 可以知道两个函数相加
exec(v1: 10, v2: 20,fn: +)
三、尾随闭包
如果将一个很长的闭包表达式作为函数的最后一个实参,
使用尾随闭包可以增强函数的可读性
尾随闭包是一个被书写在函数调用括号外面(后面)的闭包表达式
如上可以这样写
exec(v1: 10, v2: 20) { (v1,v2) in
return v1 + v2
}
//还可以简写成
exec(v1: 10, v2: 20) { (v1,v2) in
v1 + v2
}
//还可以简写成
exec(v1: 10, v2: 20) {
$0 + $1
}
四、特殊情况
如果 函数内部只有一个闭包表达式作为参数 如下,可以简化
//闭包表达式的简写
func exec(fn:(Int,Int) -> Int){
print(fn(1,2))
}
//调用时可以简写成
exec(){ $0 + $1 }
//调用时可以简写成
exec{ $0 + $1 }
闭包
注意⚠️: 闭包 和 闭包表达是有区别的
一、闭包的概念
一个函数和他所捕获的变量或常量环境组合起来的 称为闭包
一般指定义在函数内部的函数
一般它捕获的是外层函数的局部变量\常量
解释:一般指定义在函数内部的函数
// fn 函数 返回一个无参数 无返回值的函数
func fn1() -> () -> (){
func fn2(){
}
return fn2
}
//fn2 就是定义在fn1中的函数
解释 :一般它捕获的是外层函数的局部变量\常量
typealias Fn = (Int) -> Int
func getFn() -> Fn{
var num = 1
func plus(_ i:Int) -> Int{
num += i
return num
}
return plus //返回的plus和num形成了闭包
}
var a = getFn()
print(a(1)) //2
print(a(2)) //4
print(a(3)) //7
print(a(4)) //11
注意⚠️:
编译器一旦发现返回的函数中捕获了外部的变量 就会自动在堆空间开辟一块内存来存放这个变量
上面没调用一次 getFn() 就在堆去 alloc 一块内存