21、Go 函数- 匿名函数与闭包
hi,我是温新
匿名函数
什么是匿名函数
**匿名函数就是没有名字的函数。**匿名函数没有函数名,只有函数体,函数可以被作为一种类型被赋值给函数类型的变量,匿名函数往往以变量方式被传递。
匿名函数常被用于实现回调函数、闭包等。
定义匿名函数
匿名函数格式
func (参数列表) (返回参数列表) {
函数体
}
将匿名函数赋值给变量
package main
import "fmt"
func main() {
// 定义一个匿名函数并将其赋值给变量
fn := func(name string) string {
return "hello " + name
}
// 使用 fn() 调用匿名函数
fmt.Println(fn("GO"))
}
定义时调用匿名函数
package main
import "fmt"
func main() {
func(name string) {
fmt.Println("hello " + name)
}("Golang") //表示对匿名函数进行调用,传递参数值为 "Golang"
}
闭包
什么是闭包
闭包是引用了自由变量的函数,被引用的自由变量和函数一同存在,即使变量了自由变量的环境也不会被释放或删除,在闭包中只可以继续使用这个自由变量。闭包 = 函数 + 引用环境
闭包案例
在闭包内修改引用的变量
package main
import "fmt"
func main() {
// 定义一个字符串
str := "hello go"
// 定义一个匿名函数
fn := func() {
// 给字符串 str 赋予一个新的值,注意: 匿名函数引用了外部变量,这种情况形成了闭包
str = "hello golang"
// 打印
fmt.Println(str) // hello golang
}
// 执行闭包
fn()
fmt.Println(str) // hello golang
}
在这个案例中可以发现,闭包里面修改变量的值,外部的变量会受到影响。
利用闭包特性实现累加
被捕获到闭包中的变量让闭包本⾝拥有了记忆效应,闭包中的逻 辑可以修改闭包捕获的变量,变量会跟随闭包⽣命期⼀直存在,闭包 本⾝就如同变量⼀样拥有了记忆效应。
package main
import "fmt"
func main() {
// 创建一个累加器,初始值 1
c := Count(1)
fmt.Println(c()) // 2
fmt.Println(c()) // 3
fmt.Printf("c 内存地址%p\n", c)
// 创建新的累加器
c2 := Count(10)
fmt.Println(c2())
fmt.Printf("c2 内存地址为%p\n", c2)
}
// 定义一个函数 Count,返回一个 int 类型的函数
func Count(num int) func() int {
// 返回一个匿名函数(闭包)
return func() int {
num++
// 返回累加值
return num
}
}
输出结果为:
2
3
c 内存地址0x76fba0
11
c2 内存地址为0x76fb80
通过闭包实现生成器
package main
import "fmt"
func main() {
// 创建一个玩家
generator := GamePlayer("李星云")
// 返回姓名和血量
name, hp := generator()
fmt.Println(name, hp)
}
func GamePlayer(name string) func() (string, int) {
// 玩家血量
hp := 100
// 返回闭包
return func() (string, int) {
// 引用了外部的 hp 变量, 形成了闭包
return name, hp
}
}
携带参数
package main
import "fmt"
func main() {
// 函数调用
fmt.Println(Add()(3))
fmt.Println(Add2(2)(3))
}
// 无参函数,返回值是一个匿名函数,匿名函数返回一个 int 类型的值
func Add() func(b int) int {
return func(b int) int {
return b + 2
}
}
// 有参函数,返回值是一个匿名函数,匿名函数返回一个 int 类型的值
func Add2(a int) func(b int) int {
return func(b int) int {
return a + b
}
}
请登录后再评论