结合很多资料以及自己的理解和案例分析,区分匿名函数与闭包的作用和意义
匿名函数:没有名字的函数。是为了开辟封闭的变量作用域环境。用于构造闭包
以下是4种构造匿名函数的方法:
func main() {
// 方法1
func() {
fmt.Println("hello1")
}()
// 方法2
fn := func() {
fmt.Println("hello2")
}
fn()
// 方法3
fn1 := func(str string) {
fmt.Println(str)
}
fn1("hello3")
// 方法4
fn2 := func() string {
return "hello4"
}
fmt.Println(fn2())
}
/*
hello1
hello2
hello3
hello4
*/
闭包:利用匿名函数实现。可以在函数外部访问函数的变量,函数调用返回后一个没有释放资源的栈区。不需传值也在创建函数中使用自己的私有变量。闭包返回的是一个复合结构:包括匿名函数的地址以及变量的地址
优点:减少代码量,使这些局部变量始终保存着内存中,避免使用全局变量
缺点:这些局部变量不会立即销毁,浪费内存。会出现闭包的延迟
type Func func(x int) int // 定义函数类型
// 闭包
func A() Func {
var i = 1
return func(a int) int{ // 匿名函数
i++
return a+i
}
}
func main() {
res := A() // res = A.func1
fmt.Println(res(1)) // A.func1(1) = 3
fmt.Println(res(1)) // A.func1(1) = 4
}
从以上案例可以看到A是一个闭包函数,main函数中的res调用闭包A之后,返回闭包的定义。按照常规函数调用A的栈此时已经释放,但是作为闭包的A返回了匿名函数的地址和局部变量i,A没有释放自己的栈区域。res(1)实际进行闭包的执行。
我们也看到,闭包可以使用匿名函数来实现。当然也可以是实名函数或者lambda表达式