Go 匿名函数 & defer 语句

【go语言】defer、return和匿名函数的坑,但愿面试别问这些 在go语言中,defer和return的执行顺序其实有很多的学问,本人在学习过程中,也是被defer和return的组合拳打得神志恍惚,想在网上找一找大神讲解,但是找了半天没找到太全面的,最后在查阅了资料,并敲了几个代码后好不容易捋顺了思路,特意来写了这篇文章,希望能对同样迷茫的初学者带来一些帮助。 关于defer的作用,就不多做赘述了,下面将直接通过四个例子来说明defer和return的运行机制。 例子1: func demo01() int { n := 10 defer func() { 阅读详情

在 Go 语言中,函数是一种基本的代码组织方式。除了普通函数,Go 语言还提供了匿名函数、函数递归和 defer 语句等高级特性,本篇技术博客将详细介绍这些特性的使用方法和注意事项。

匿名函数

匿名函数是一种没有函数名的函数,可以直接定义和调用。匿名函数通常用于实现闭包和简化代码结构。

定义匿名函数

在 Go 语言中,可以使用关键字 func 定义一个匿名函数。匿名函数的定义格式与普通函数类似,只是没有函数名。例如:

func() {
    fmt.Println("Hello, world!")
}()

在上面的示例中,定义了一个匿名函数,该函数没有参数和返回值,直接输出一个字符串。匿名函数的定义后面加上一对括号,表示立即执行该函数。

将匿名函数赋值给变量

在 Go 语言中,可以将匿名函数赋值给变量,从而可以像普通函数一样调用。例如:

add := func(a, b int) int {
    return a + b
}
c := add(1, 2)
fmt.Println(c) // 输出 3

在上面的示例中,将一个匿名函数赋值给变量 add,表示定义了一个名为 add 的函数,可以像普通函数一样调用。

匿名函数作为参数

在 Go 语言中,可以将匿名函数作为参数传递给其他函数。这种用法通常用于实现回调函数和函数式编程。例如:

func apply(arr []int, f func(int) int) []int {
    result := make([]int, len(arr))
    for i, v := range arr {
        result[i] = f(v)
    }
    return result
}

arr := []int{1, 2, 3, 4, 5}
square := func(x int) int { return x * x }
result := apply(arr, square)
fmt.Println(result) // 输出 [1 4 9 16 25]

在上面的示例中,定义了一个名为 apply 的函数,该函数接受一个整数数组和一个匿名函数作为参数。函数内部将匿名函数应用到数组的每个元素上,并返回一个新的数组。

函数递归

函数递归是指函数调用自身的行为。函数递归通常用于解决需要重复执行相同操作的问题,例如计算阶乘、斐波那契数列等。

递归函数的特点

递归函数有以下几个特点:

  • 递归函数必须有一个终止条件,否则会陷入无限递归。
  • 递归函数的调用过程会使用栈来保存每次调用的信息,因此递归深度过大可能会导致栈溢出。

递归函数的实现

在 Go 语言中,函数递归的实现与普通函数类似,只是在函数内部调用自身。例如,下面是一个计算阶乘的递归函数实现:

func factorial(n int) int {
    if n == 0 {
        return 1
    }
    return n * factorial(n-1)
}

fmt.Println(factorial(5)) // 输出 120

在上面的示例中,定义了一个名为 factorial 的递归函数,用于计算输入值的阶乘。函数内部使用了一个终止条件 n == 0,如果 n 的值等于 0,就返回 1,否则返回 n * factorial(n-1)。

defer 语句

defer 语句是 Go 语言中的一个特殊语句,用于在函数返回之前执行一些清理工作或者保证某些语句在函数结束时一定会被执行。defer 语句通常用于释放资源、关闭文件、解锁锁等操作,能够有效避免资源泄漏和错误处理的重复代码。

defer 语句的特点

defer 语句有以下几个特点:

  • defer 语句可以在函数内部任何位置定义,但是一定会在函数返回前执行。
  • 如果有多个 defer 语句,它们会按照定义的逆序依次执行。
  • defer 语句中的函数参数在定义时就已经确定,但是函数的执行会在函数返回前才发生。

defer 语句的使用场景

defer 语句通常用于以下场景:

  • 关闭文件或者释放资源。例如:
file, err := os.Open("example.txt")
if err != nil {
    return err
}
defer file.Close()
// 使用文件进行读写操作

在上面的示例中,使用 os.Open 函数打开文件,如果打开文件发生错误,就直接返回。否则,在函数返回前使用 defer 语句关闭文件,保证文件资源能够被正确释放。

  • 解锁。例如:
var mu sync.Mutex
mu.Lock()
defer mu.Unlock()
// 程序的其他代码

在上面的示例中,使用 defer 语句保证在函数返回前一定会解锁锁,避免出现死锁的情况。

  • 记录函数执行时间。例如:
func measureTime(start time.Time) {
    elapsed := time.Since(start)
    log.Printf("函数执行时间:%s", elapsed)
}
start := time.Now()
defer measureTime(start)
// 程序的其他代码

在上面的示例中,使用 defer 语句记录函数的执行时间,并在函数返回前输出日志信息。

总结

本篇技术博客介绍了 Go 语言中的匿名函数、函数递归和 defer 语句等高级特性。匿名函数可以用于实现闭包和简化代码结构,函数递归可以解决需要重复执行相同操作的问题,defer 语句可以保证某些语句在函数结束前一定会被执行,能够有效避免资源泄漏和错误处理的重复代码。掌握这些特性能够让 Go 语言的编程更加高效和灵活。

Go函数--defer语句 1 defer语句 该语句用于延迟调用指定的函数,它只能出现在函数或方法的内部,由defer 关键字以及针对某个函数的调用表达式组成。这里被调用的函数称为延迟函数。简单的示例如下: func outerFunc() { defer fmt.Println("函数执行结束前一刻才会被打印") fmt.Println("第一个被打印") } 《代码说明》defer关键字后面是针对fmt.Println()函数的调用表达式。这里的outerFunc()称为外围函数。 defer语句经常用 阅读详情

相关推荐

Go defer 原理剖析篇 — 搞懂 golang defer 所有的使用姿势

文章目录defer 的特性延迟调用LIFO作用域异常场景使用姿势并发同步锁场景资源释放panic-recover总结 更多干货:关注公众号 奇伢云存储 Golang 的 defer 是什么?通俗来讲就是延迟调用。defer 会在当前函数返回之前执行 defer 注册的函数。比如 defer func_x( ) 这样语句会让你注册一个函数变量到 defer 的全局链表中,在 defer 语句所在的函数退出之前调用。 笔者使用一段时间 Golang 之后,对 Golang defer 的理解认为作用有两点

伢之国 1010

一文了解Go语言的匿名函数

匿名函数是一种没有函数名的函数。它是在代码中直接定义的函数,没有被分配一个显式的标识符或名称。匿名函数通常用于需要临时定义、简短使用或在其他函数内部使用的情况。Go语言对匿名函数是支持的,其定义方式非常简单,func// 在这个例子中,我们在main函数内部定义了一个匿名函数,并将其赋值给了变量greet")// 调用匿名函数greet()在这个示例中,我们在main函数内部定义了一个匿名函数,并将其赋值给了变量greet。匿名函数体内的代码打印了"Hello, World!通过调用。

chenjiazhanxiao的博客 2119

图解5G HARQ-ACK反馈:从DCI解析到PUCCH发送的完整数据流

本文详细解析了5G通信系统中HARQ-ACK反馈机制的完整流程,从DCI解码到PUCCH发送的实战指南。重点介绍了HARQ-ACK码本生成、DCI关键参数解读以及PUCCH资源映射等核心技术环节,帮助工程师深入理解5G NR中的数据传输可靠性保障机制。

weixin_27722377的博客 396

go语言defer与匿名函数

  学习go语言的时候,遇到了一个例子 func main() { a := []int{1, 2, 3, 4} defer func(a []int) { fmt.Printf("a: %v\n", a) }(a) a[0], a[1] = a[2], a[3] defer func() {fmt.Println("aloha")}() }...

IronWring_Fly的博客 1585

android6 usb默认文件管理,不弹RSA配对提示框

本文修改针对 高通 Android6.0.1 出user版本时 https://www.cnblogs.com/Jokeyyu/p/7424262.html http://blog.youkuaiyun.com/sinc00/article/details/44957943 diff --git a/frameworks/base/packages/SystemUI/src/com/android...

木叶风的博客 692

vCenter Server出现no healthy upstream的解决方法

可以通过"VMware vCenter Server Management(服务)"来排查问题,在网页里面找到“服务”模块,会发现有很多服务没有启动起来,而且手动启动也无法启动。7.0 地址后,页面出现“no healthy upstream”,无法正常登录vCenter,重启后依旧如此,该故障的前提是没有对vCenter做过任何配置,如下图所示。于是用命令查询是否有证书过期,发现真有多个服务依赖的证书在当天早上过期。使用如下命令尝试打开服务发现不分服务可以打开,不分服务无法打开。

1万+

defer和匿名函数结合使用

package main import “fmt” func main( ) { a := 10 b := 20 //后执行 defer func (a,b int ) { fmt.Printf(“a = %d,b = %d\n”,a,b) } ( a,b) //()代表匿名函数,把参数传递过去,已经先传递参数,只是没有调用,直接是10和20 //先执行 a = 111 b = 222 fmt.P...

ymeng9527的博客 377

uniapp - 实现集成调用zebra斑马打印机+打印标签+打印二维码详细实例代码,通过蓝牙连接打印机打印与通过打印机IP和端口两种方式适配斑马打印机(全平台兼容H5、微信小程序、苹果安卓App)

uniapp适配斑马打印机 实现标签打印,uniapp适配斑马打印机实现标签打印,uniapp调用zebra斑马打印机打印标签,uniApp连接传统蓝牙的斑马打印机打印,实现标签打印功能uniapp 蓝牙连接斑马打印机发送zpl指令打印,适配斑马(Zebra)牌打印机,小程序调用蓝牙打印机完整代码,uniapp 打印机wifi链接 蓝牙链接,uniapp斑马打印机,实现二维码标签展示以及打印,APP端连接打印机打印小票和标签,uniapp使用斑马打印中文不出来,打印机连接不上,打印没反应怎么办,打印报错,斑

🏆 前端领域优质创作者 1万+

go基础之函数,匿名函数,defer,panic/recover

函数 函数是一个组织好的,可以重复使用的,用于执行,指定任务的代码块。 Go语言支出,函数,匿名函数和闭包 package main import ( "fmt" "strings" ) func main() { // 定义函数的格式 // func 函数名(参数)(返回值){ // } //通过函数名就可以调用函数,函数有参数的情况下, // 必须填写参数,调用函数的结果,就是返回值 fmt.Println("fu1函数", fu1(3, 2))

weixin_44865158的博客 330

【python股票价格预测】基于CNN-LSTM的股票价格预测(附python代码)

【python股票价格预测】基于CNN-LSTM的股票价格预测(附python代码)

k8291121的博客 2008

基于多传感器融合的智身四足机器狗楼梯环境SLAM系统设计与实现

本文设计了一种基于多传感器融合的四足机器狗楼梯环境SLAM系统。系统采用Jetson Orin NX为主控制器,集成RealSense D435i深度相机和Livox Mid360激光雷达,在ROS2框架下实现平面定位精度<5cm、楼梯环境下导航不漂移的目标。通过多层次传感器融合策略、运动学约束优化和状态切换机制,解决了楼梯环境下的定位累积误差问题,实现了平面与楼梯环境的自动识别切换及精度复位功能。硬件设计注重传感器布局优化和精确标定,软件架构采用分层设计,确保实时性能。该系统为四足机器人在复杂地形中

huanghm88的专栏 242

Go defer函数

函数返回前执行的函数 在电泳普通函数或方法前加关键字`defer`,就完成了`defer`所需要的语法 可以在一个函数中执行多条`defer`语句,它们的执行顺序与声明顺序相反 无论包含`defer`语句的函数是通过`return`正常结束,还是由于`panic`导致的异常结束`defer`后的函数都会被执行 函数体内某个变量作为`defer`匿名函数的参数,则在定义`defer`时已经获得了拷贝,否则则是引用某个变量的地址 // defer函数 func main() { defer log.

weixin_40123451的博客 374

李宏毅2025《机器学习》第一讲-生成式AI:技术突破和未来发展

本文基于台湾大学李宏毅教授的“一堂课搞懂生成式人工智慧的技术突破与未来发展”课程内容,系统性地梳理了生成式AI的核心概念、技术原理、发展演进以及未来趋势。文章从AI的“行为”入手,通过生动的实例展示了其强大的生成与推理能力;进而深入剖析其底层运作机制,阐释了“万物皆为令牌(Token)”、自回归生成、Transformer架构等核心原理;接着,文章追溯了通用AI模型从“专才”到“通才”的演进历程;最后,探讨了如何通过微调(Fine-tuning)、模型编辑(Model Editing)等技术赋予AI新的能力

木鱼时刻的专栏 2295

【GoLang #4】:Go 语言 函数详述(定义调用 | 匿名函数 闭包 | defer)

无需声明原型、支持多返回值和命名参数、函数可作为值传递,但不支持嵌套和重载。函数定义使用func关键字,支持值传递(默认)和通过指针实现引用传递效果。特别的是,Go采用多返回值机制,非常适合错误处理模式,并可命名返回值提升可读性。 匿名函数可直接定义使用或赋值给变量,支持闭包特性(函数+引用环境),能访问外部作用域变量。闭包常用于保持状态(如计数器)或延迟执行。这些特性使Go函数灵活强大,适合构建高效可靠的程序。

island1314的博客 1027

基于simulink的电气弹簧ES稳压控制模型仿真

若要补偿母线电压的谐波,需控制ES上的谐波,即在单闭环母线电压有效值控制的基础上,增加谐波抑制环节来进行谐波控制,现有的各种检测和抑制谐波的方法有采用模拟滤波器、傅里叶分析进行谐波分析、基于瞬时无功功率理论的方法等。当关键负载ZC为电流源型非线性负载时,电路原理图如图7所示,由于电流源型非线性负载可以等效为谐波电流源,关键负载电流ic便会含有谐波分量,导致输电线电流is和母线电压VS同样会含有谐波分量,导致供电质量的严重下降,对用电设备的正常工作造成影响。分别为流过线路阻抗、非关键负载、关键负载的电流,

FPGA/MATLAB学习教程/源码/项目合作开发 1633

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

go语言的defer语句

go语言defer语句的用法 参考:https://www.jianshu.com/p/5b0b36f398a2 defer的语法 defer后面必须是函数调用语句,不能是其他语句,否则编译器会出错。 package main import "log" func foo(n int) int { defer n++ //defer log.Println("n=", ...

jacke121的专栏 2641

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

golang defer 语句匿名函数和具名函数的区别

如果 defer 语句调用的是一个具名函数,那就要注意该具名函数的某个参数是不是引用了另外一个函数。假如 defer 语句为 defer A(B()) ,那么 defer 语句在注册的时候就会执行函数 B() , 但是函数 A() 的执行则延迟到 defer 外围函数即将退出时。 func (sm *SyncMap) Put(k, v string) { sm.lock.Lock(); d

Allen_jinjie 的技术空间 2536

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

Go语言 defer 详解

在Go语言中,defer用于注册延迟执行的函数。 这些被推迟的函数会在外层函数返回之前按照后进先出(LIFO)的顺序执行。 一句话总结: 👉 defer就是安排好“临走前要做的事”

gopher123的博客 1901

Go返回匿名函数和Defer

Go返回匿名函数和Defer匿名函数defer 匿名函数 Go中有return func(param1 paramType1, param2 paramType2, …, param paramType) (returnType1, returnType2,…) 返回一个匿名函数的指针,我们在打印时可以打印出这个函数的地址。也可以通过返回值调用这个方法。举例说明 //main.go type ( annoFunc func(param string) error ) func main() { ann

qq_18478183的博客 393

【Go面试向】defer与time.sleep初探

【Go面试向】defer与time.sleep初探 面试官:请你用defer与time.sleep写一个计算函数运行时间的程序,你会怎么写?

寸铁的博客 1908

golang善用go func和defer

一、error与panic: error:可预见的错误 panic:不可预见的错误,panic一般通过defer中的recover()捕获 对于有风险的代码,若发生panic则会导致程序异常退出,例如数组越界。 1. panic的操守 panic是有秩序的,退出之前会执行完先处理完当前goroutine已经defer【挂上去】的任务,若某个defer在panic之后,则不会被执行。 pani...

NNnora的博客 1万+

golang中defer语句使用小结

defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数据库连接、断开socket连接、解锁一个加锁的资源。语句,C++语言里的析构函数(Destructor)可以起类似的作用,C++语言机制担保在对象被销毁前一定会执行析构函数中的代码。C++中的析构函数析构的是对象,Go中的defer析构的是函数。上述代码打印出来的值是:11。Go中的panic类似其它语言中的抛出异常,panic后面的代码不再执行(panic语句前面的defer语句会被执行)。

墨痕诉清风的博客 678

Go | 单个defer & 多个defer &匿名函数

单个defer 例一: defer fmt.Print("aaaaaaaaaaaaaa") fmt.Print("bbbbbbbbbbbbbb") 放在一个闭包上 func(){ defer fmt.Print("aaaaaaaaaaaaaa") }() fmt.Print("bbbbbbbbbbbbbb") 多个defer下 defer fmt.Print("aaa") ...

GC怪兽的Blog 377

go-defer语句

Go语言中的defer语句也非常独特。 defer语句仅能被放置在函数或方法中。 它由关键字defer和一个调用表达式组成。 调用表达式所表示的既不能是对Go语言内建函数的调用 也不能是对Go语言标准库代码包unsafe中的那些函数的调用。 实际上,满足上述条件的调用表达式被称为表达式语句。 func readFile(path string) ([]...

dianyun7150的博客 112

Go最新避免defer陷阱:拆解延迟语句,掌握正确使用方法(1),2024年最新Golang面试你必须要知道的那些知识

通过以上示例,我们可以明确体现出使用匿名函数和非匿名函数作为defer的参数的区别。匿名函数可以直接在defer语句中定义,并访问外部变量,而非匿名函数需要先定义好函数,然后将函数名作为参数传递。网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。需要这份系统化的资料的朋友,可以添加戳这里获取一个人可以走的很快,但一群人才能走的更远!

2401_84919754的博客 767

Golang教程二(判断,循环语句,函数,指针,init,defer)

/ 参数类型一样,可以合并在一起// 多个参数。

qq_22321199的专栏 1422
上一篇: Go 语言函数
下一篇: Go 容器类
GeeCode
博客等级 码龄3年 2粉丝 58原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值