21、Go 函数- 匿名函数与闭包

作者: 温新

分类: 【Go基础】

阅读: 554

时间: 2023-08-29 15:52:20

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
    }
}
请登录后再评论