golang日常开发系列之一--defer的那些坑"

简介: golang日常开发系列之一--defer的那些坑"

最近集中开发了一波golang, 因此打算开启一个坑,就叫golang日常开发系列,用于总结这段时间内遇到的各种奇奇怪怪的关于golang开发的一些问题, 后续如果有新奇的问题也会加以补充.


废话不多说,我们直接进入系列之一,看看defer使用过程中有哪些坑,如何解决?



一、所谓的"坑"


func logErr(err error) {
 fmt.Println(err)
}
func main() error {
 var err error
    defer logErr(err)
 err = fmt.Errorf("error")
 return err
}


上面的代码试图在main函数退出的时候,将err变量打印出来。你认为会输出什么呢?nil 还是 error ? 一般我们会想err再return之前已经从nil变成非nil值,所以执行defer的时候应该会打印error吧?很遗憾,结果并不是这样,代码的输出是nil



二、原因


为什么会出现与我们预期不同的结果呢?因为logErr是一样函数,注册defer LogErr(err)的时候,会将err当前值nil传递给LogErr。当函数退出执行defer代码的时候,打印的便是传入的形参值nil.


之所以我们觉得不符合预期,还是因为对golang defer和函数的运行机制理解不到位




三、解决


3.1 指针法


明白了原因,解决方法就出来了。logErr不是传值吗,既然传err不奏效(因为err后续会重新被赋值),我传指向err的指针行不行,这样不管err值如何变化,我通过指针都能获取最新的err值。


func logErr(err *error) {
    fmt.Println(*err)
}
func main() error {
 var err error
    defer logErr(&err)
 err = fmt.Errorf("error")
 return err
}


以上代码输出结果为error



3.2 闭包法


我们知道使用闭包时,闭包会引用外部的变量, 根据闭包的这个特性,也可以实现我们的需求


func logErr(err error) {
    fmt.Println(err)
}
func main() error {
 var err error
    defer func() {
        logErr(err)
    }()
 err = fmt.Errorf("error")
 return err
}


在注册defer时,err的引用会被传入闭包中。不管err后来如何变化,当执行defer时,函数logErr获取到的必然是最新的err值

相关文章
|
2月前
|
存储 Go C语言
如何用Go开发eBPF程序
【2月更文挑战第7天】
|
2月前
|
开发框架 安全 中间件
Go语言开发小技巧&易错点100例(十二)
Go语言开发小技巧&易错点100例(十二)
29 1
|
6天前
|
前端开发 Java Go
开发语言详解(python、java、Go(Golong)。。。。)
开发语言详解(python、java、Go(Golong)。。。。)
|
1月前
|
JSON Go API
Go语言网络编程:HTTP客户端开发实战
【2月更文挑战第12天】本文将深入探讨使用Go语言开发HTTP客户端的技术细节,包括发送GET和POST请求、处理响应、错误处理、设置请求头、使用Cookie等方面。通过实例演示和代码解析,帮助读者掌握构建高效、可靠的HTTP客户端的关键技术。
|
2月前
|
Go
Go语言开发小技巧&易错点100例(十一)
Go语言开发小技巧&易错点100例(十一)
16 0
|
2月前
|
存储 Java Go
Go语言开发小技巧&易错点100例(十)
Go语言开发小技巧&易错点100例(十)
19 0
|
2月前
|
Go 开发者
Go语言开发小技巧&易错点100例(九)
Go语言开发小技巧&易错点100例(九)
15 0
|
2月前
|
JSON Go 数据格式
Go语言开发小技巧&易错点100例(八)
Go语言开发小技巧&易错点100例(八)
17 0
|
2月前
|
消息中间件 IDE Go
Go语言开发小技巧&易错点100例(七)
Go语言开发小技巧&易错点100例(七)
18 0
|
2月前
|
运维 监控 Go
Go语言开发小技巧&易错点100例(六)
Go语言开发小技巧&易错点100例(六)
19 0