golang 基础(28)defer

《golang 基础(28)defer》 square-gopher.png

资源管理与出错处理

defer 调用

有的时候我们需要程序发生错误后需要进行后续的处理,例如关闭文件、结束网络连接等。这时候我们就会用到 def ,如果是 java 的 developer 可以理解为 finally。

  • 确保在函数结束时发生
  • 参数在 defer 语句时计算
  • defer 列表为后进先出
var wg sync.WaitGroup

func say(s string){
    for i:=0; i < 3; i++ {
        fmt.Println(s)
        time.Sleep(time.Millisecond * 100)
    }

    wg.Done()
}

func main(){
    wg.Add(1)
    go say("Hey")
    wg.Add(1)
    go say("There")

    wg.Add(1)
    go say("Hi")
    wg.Wait()
}

func say(s string){
    defer wg.Done()
    for i:=0; i < 3; i++ {
        fmt.Println(s)
        time.Sleep(time.Millisecond * 100)
    }

}

《golang 基础(28)defer》 ![600_478303968.jpeg](https://upload-images.jianshu.io/upload_images/8207483-08dcf0aacf26d768.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

func tryDefer(){
    fmt.Println(1)
    fmt.Println(2)
}

func main(){
    tryDefer()
}
1
2
func tryDefer(){
    defer fmt.Println(1)
    fmt.Println(2)
}

使用 defer 就会

2
1

defer 相对来说是一个栈先进后出

func tryDefer(){
    defer fmt.Println(1)
    defer fmt.Println(2)
    fmt.Println(3)
    
}
3
2
1

加了 defer 就不怕程序中间 return 甚至是 panic

func tryDefer(){
    defer fmt.Println(1)
    defer fmt.Println(2)
    fmt.Println(3)
    return
    fmt.Println(4)
}
func writeFile(filename string){
    file,err := os.Create(filename)
    if err !=nil {
        panic(err)
    }
    defer file.Close()
    writer := bufio.NewWriter(file)
    defer writer.Flush()

    f := fib.Fibonacci()

    for i := 0; i < 20; i++{
        fmt.Fprintln(writer,f())
    }
}

避免我们忘记,可以只写 defer

for i:=0; i < 100; i++ {
        defer fmt.Println(i)
        if i == 30 {
            panic("printed too many")
        }
    }
3
2
1
0
panic: printed too many
    原文作者:zidea
    原文地址: https://www.jianshu.com/p/118947de97ed
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞