1.匿名函数和闭包的概念
匿名函数: 声明函数时不显式声明函数名。
闭包: 简单来说就是一个函数定义中引用了函数外定义的变量,并且该函数可以在其定义环境外被执行。这样的一个函数我们称之为闭包。实际上闭包可以看做一种更加广义的函数概念。因为其已经不再是传统意义上定义的函数。
go语言中的匿名函数声明方法类似于js,而闭包声明类似于python。
demo:
package main
import "fmt"
func main() {
a := 10
str := "golang"
//匿名函数,没有函数名字
//可以捕获同一个作用域的变量
f1 := func() {
fmt.Println(a, str)
}
f1()
//给一个函数类型起别名
type FuncType func() //函数没有参数,没有返回值
// 声明变量
var f2 FuncType
f2 = f1
f2()
// 定义匿名函数的同时调用
func() {
fmt.Println(a, str)
}() // 后面的()代表调用此匿名函数
// 带参数的匿名函数
func(i, j int) {
fmt.Println(i + j)
}(5, 6)
// 匿名函数有参有返回值
var b = func(i, j int) int {
return i + j
}(5, 7)
fmt.Println(b)
func() {
//闭包以引用的方式捕获外部变量,里面改了外面的变量也会被改变
a = 66
str = "abc"
fmt.Println("内部:", a, str)
}()
fmt.Println("外部: ", a, str)
}
2.闭包的特点
- 闭包不关心这些捕获了的变量和常量是否已经超出了作用域,只要闭包还在使用这些变量,那么这些变量就不会被垃圾回收
- 我们看到的变量的生命周期不由它的作用域决定,当f返回后,变量x仍然隐式的存在于f中。
package main
import "fmt"
// 返回一个匿名函数
func test() func() int {
var x int
return func() int { //闭包
x++
return x * x
}
}
//闭包不关心这些捕获了的变量和常量是否已经超出了作用域,只要闭包还在使用这些变量,那么这些变量就不会被垃圾回收
//我们看到的变量的生命周期不由它的作用域决定,当f返回后,变量x仍然隐式的存在于f中。
func main() {
var f = test()
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
fmt.Println(f())
}