golang 详解defer

简介:

什么是defer

defer用来声明一个延迟函数,把这个函数放入到一个栈上, 当外部的包含方法return之前,返回参数到调用方法之前调用,也可以说是运行到最外层方法体的"}"时调用。我们经常用他来做一些 资源的释放,比如关闭io操作
 
复制代码
func doSomething(fileName string) {
    file,err := os.Open(fileName)
    if err != nil {
    panic(err)
    }
    defer file.Close()
}
复制代码

 

defer 可以保证方法可以在外围函数返回之前调用。有点像其他言的 try finally
try{
}finally{
}
 

 

defer 读写外部变量

  defer声明的函数读写外部变量,和闭包差不多。比如下面的代码

复制代码
func doSomething() {
    v := 10
    defer func() {
        fmt.Println(v)
        v++
        fmt.Println(v)
    }()
    v += 5
}
复制代码

输出为

15
16

  就像闭包一样,如果不是defer函数方法内的变量会向上一层函数访问变量,重新做计算。

defer 读写命名的返回值

    这个例子中,defer声明的方法,给命名的返回值自增1
 
复制代码
1 func doSomething() (rev int) {
2     defer func() {
3         rev++
4     }()
5 
6     return 5
7 }
复制代码

  第6行的return 相当于

return rev = 5

  defer 声明的匿名函数会在return 之前执行,相当于

rev = 5
// 执行defer方法
rev++
//然后return
return

  所以结果是6

  我把代码做一点点修改

复制代码
1 func doSomething() (rev int) {
2     v := 10
3     defer func() {
4         v++
5     }()
6 
7     return v
8 }
复制代码

  第7行返回的是局部变量v.   

return v 相当于 return rev = v

  defer 函数里是对局部变量v的操作,所以与返回的rev没有关系。所有执行的结果是:10

defer 执行顺序

当有多个defer时执行顺序逆向的,后进先出:
func doSomething() {
    defer fmt.Println(1)
    defer fmt.Println(2)
}

 

会先输出2,再输出1
 

 defer 处理异常

  panic抛出异常后,如果不处理应用程序会崩溃。为了防止程序崩溃,我们可以在defer的函数里使用recover来捕获中异常:
复制代码
func doSomething() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Print(err)
        }
        
    }()

    fmt.Println("Running...")
    panic("run error")
}
复制代码

输出:

Running...
run error

recover 会捕获panic的异常。我再把代码做一点点修改:

复制代码
func doSomething() {
    defer func() {
        if err := recover(); err != nil {
            fmt.Print(err)
        }
        
    }()

    defer func() {
        panic("defer error")
    }()

    fmt.Println("Running...")
    panic("run error")
}
复制代码

 

输出结果

Running...
defer error

因为 recover()只捕获最后一次panic

目录
相关文章
|
4月前
|
Go
Go语言中defer的执行顺序详解
【2月更文挑战第22天】
75 4
|
10月前
|
Cloud Native Go
GO 中的 defer 有哪些注意事项?上
GO 中的 defer 有哪些注意事项?上
|
11月前
|
Go
Go语言编程的一大杀器!详解defer语句
Go语言编程的一大杀器!详解defer语句
51 0
|
1月前
|
存储 Go
掌握 Go 语言的 defer 关键字
掌握 Go 语言的 defer 关键字
|
21天前
|
Go
实验深度理解Go中try...catch...的panic、defer、recover用法
文章通过实验代码演示了Go语言中如何使用panic、defer和recover函数来模拟try...catch...的异常处理机制,并详细解释了每个函数的作用和在异常处理中的使用场景。
24 0
|
1月前
|
Serverless Go
Golang 开发函数计算问题之defer 中的 recover() 没有捕获到 如何解决
Golang 开发函数计算问题之defer 中的 recover() 没有捕获到 如何解决
|
1月前
|
人工智能 数据库连接 Go
golang defer 详解
golang defer 详解
32 0
|
4月前
|
Go 开发者
Golang深入浅出之-Go语言 defer、panic、recover:异常处理机制
Go语言中的`defer`、`panic`和`recover`提供了一套独特的异常处理方式。`defer`用于延迟函数调用,在返回前执行,常用于资源释放。它遵循后进先出原则。`panic`触发运行时错误,中断函数执行,直到遇到`recover`或程序结束。`recover`在`defer`中捕获`panic`,恢复程序执行。注意避免滥用`defer`影响性能,不应对可处理错误随意使用`panic`,且`recover`不能跨goroutine捕获panic。理解并恰当使用这些机制能提高代码健壮性和稳定性。
80 2
|
4月前
|
Java Go 区块链
【Go语言专栏】Go语言中的延迟执行与defer语句
【4月更文挑战第30天】Go语言的延迟执行与defer语句用于资源释放和错误处理。defer通过关键字定义,函数返回时执行,顺序与定义相反。参数在定义时求值。应用包括资源释放、错误处理、成对操作和函数包装,是Go编程的关键特性。
39 0
|
11月前
|
安全 Go
Golang 语言中的 defer 怎么使用?
Golang 语言中的 defer 怎么使用?
40 0