Go语言中闭包(Closure)基本示例与注意事项

 更新时间:2026年10月02日 11:13:54   作者:会编程的土豆  
在Go语言中闭包(Closure)是一种特殊的函数,它可以捕获其创建时所在作用域中的变量,闭包通常与匿名函数一起使用,匿名函数可以访问并操作不在其参数列表中的外部变量,这篇文章主要介绍了Go语言中闭包(Closure)基本示例与注意事项的相关资料,需要的朋友可以参考下

闭包是 Go 中非常重要的概念,允许函数访问和操作其外部作用域的变量。理解闭包对于实现回调、累加器、工厂函数等场景非常有用。

一、闭包的概念

闭包是一个函数,它可以捕获并使用定义在其外部作用域的变量,即使外部函数已经返回,这些变量依然存在于内存中。

简单理解:

闭包 = 函数 + 它捕获的外部变量

二、基本示例

package main

import "fmt"

func main() {
    add := func(a, b int) int {
        return a + b
    }

    fmt.Println(add(3, 5)) // 8
}

这是最基本的函数,也可以看作闭包,但没有捕获外部变量。

三、闭包捕获外部变量

package main

import "fmt"

func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

func main() {
    f := adder()
    fmt.Println(f(1)) // 1
    fmt.Println(f(2)) // 3
    fmt.Println(f(3)) // 6
}

说明:

  • adder 返回一个函数
  • 返回的函数可以访问 adder 内部的 sum
  • 每次调用返回函数,sum 都会累加,闭包保存了 sum 的状态

四、闭包注意事项

  • 捕获变量是引用
func main() {
    funcs := []func(){}
    for i := 0; i < 3; i++ {
        funcs = append(funcs, func() {
            fmt.Println(i)
        })
    }
    for _, f := range funcs {
        f() // 输出 3 3 3,而不是 0 1 2
    }
}

原因:

  • 闭包捕获的是 i 的地址,循环结束后 i = 3,所以每个闭包都打印 3。

解决办法:

for i := 0; i < 3; i++ {
    x := i
    funcs = append(funcs, func() {
        fmt.Println(x)
    })
}

输出:

0
1
2
  • 闭包可以作为回调函数
func callback(f func(int) int) {
    fmt.Println(f(10))
}

func main() {
    y := 5
    callback(func(x int) int {
        return x + y
    }) // 输出 15
}

闭包可以捕获外部变量 y。

  • 闭包的应用场景
  • 累加器(上例)
  • 工厂函数(生成自定义函数)
  • 回调函数
  • 延迟执行或装饰器模式

五、闭包总结

  • 闭包 = 函数 + 捕获的外部变量
  • 捕获的变量在闭包内是引用,修改会影响外部变量
  • 循环中使用闭包需注意变量捕获问题
  • Go 中闭包常用于累加器、回调和函数工厂
  • 理解闭包是深入掌握 Go 函数式编程风格的关键

到此这篇关于Go语言中闭包(Closure)基本示例与注意事项的文章就介绍到这了,更多相关Go语言闭包Closure内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅谈Golang如何使用Viper进行配置管理

    浅谈Golang如何使用Viper进行配置管理

    在Golang生态中,Viper是一个不错的开源配置管理框架,这篇文章主要为大家介绍了Golang如何使用Viper进行配置管理,需要的可以参考一下
    2023-06-06
  • go RWMutex的实现示例

    go RWMutex的实现示例

    本文主要来介绍读写锁的一种Go语言的实现方式RWMutex,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • 聊聊Go语言编译github上的项目遇到的坑

    聊聊Go语言编译github上的项目遇到的坑

    这篇文章主要介绍了解决Go语言编译github上的项目遇到的坑,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • Go类型安全的HTTP请求示例详解

    Go类型安全的HTTP请求示例详解

    这篇文章主要为大家介绍了Go类型安全的HTTP请求示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • 使用go-selfupdate实现Golang应用自更新

    使用go-selfupdate实现Golang应用自更新

    go-selfupdate是一个功能强大的开源库,专门为Go语言应用程序提供无缝的自更新功能,无论你是开发桌面应用、命令行工具还是服务器程序,这个工具都能让你的应用保持最新状态,下面就来详细了解一下
    2026-07-07
  • golang 使用chromedp获取页面请求日志network

    golang 使用chromedp获取页面请求日志network

    这篇文章主要为大家介绍了golang 使用chromedp获取页面请求日志network方法实例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • 浅析Go语言中的缓冲区及其在fmt包中的应用

    浅析Go语言中的缓冲区及其在fmt包中的应用

    这篇文章主要为大家详细介绍了Go语言中的缓冲区及其在fmt包中的应用的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2024-01-01
  • Go语言类型系统入门:变量、常量、数据类型一次讲透

    Go语言类型系统入门:变量、常量、数据类型一次讲透

    还在为Go的类型系统头疼吗?本文用最直白的方式讲透变量声明(var与:=)、常量(const与iota)以及四大数据类型,你将明白为什么Go写起来像动态语言,彻底搞清数组与切片的区别,避开新手最容易犯的5个错误,让Go类型系统成为你写出安全代码的基石
    2026-08-08
  • Go语言实现遍历文件夹

    Go语言实现遍历文件夹

    这篇文章主要为大家详细介绍了Go语言实现遍历文件夹的相关方法,文中的示例代码讲解详细,具有一定的参考价值,感兴趣的小伙伴可以了解一下
    2023-05-05
  • Go语言中TCP/IP网络编程的深入讲解

    Go语言中TCP/IP网络编程的深入讲解

    这篇文章主要给大家介绍了关于Go语言中TCP/IP网络编程的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-05-05

最新评论