go语言 golang defer 关注点

htyu_0203_39 · · 3692 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

大家都了解C++有构造函数和析构函数,加之每一个栈对象都有其严格的作用或,离开则自动调用其析构函数,以此来保证释放其掌控的资源,如:内存,文件,socket,数据库链接等, 其它一些语言提供类似的机制,如: init, deinit等, 那么对于追求大道至简的golang, 她没有提供构造函数和析构函数的概念, 但是她也不可避免要处理资源的自动释放问题, 所以其提供了defer,  如: defer f() 用于延迟调用f(), 当此语句所在函数执行完(return执行完)后,开始以“后进先出”的顺序执行defer语句。但是defer不是一定会被执行的,我简单归总了一下,怕我以后忘记, 见测试代码:


package main


import (

       "fmt"
       //"log"
       //"os"
)


func main() {

       fmt.Println("test\n")


       if true {
              fmt.Println("add defer")
              defer fmt.Println("defer run!!") //虽然在if的小block中, 但是defer只会到函数执行完时才执行,而不是在离开if作用域时执行。
       }
       fmt.Println("test end\n")
       //1. defer不会执行了.
       //log.Fatal()
       //os.Exit(1)

       //2. defer会照常执行。
       //log.Panic()
       //panic(nil)
       //return
       //reach the end of the function normally.


}
通常我们只把os.Exit用于test case代码中, 生产代码中很少用,可能有用它的理由就是程序退出时向操作系统报告状态码,但是会中断defer的执行,为了使资源被正确释放
掉, 我们可以采用以下代码的处理方式, 把业务逻辑代码单独封装在一个函数中, 在退出这个函数时,注意只是在函数执行完return以后,与作用域无关 一切defer皆自动执行完,不用再担心os.Exit()了,见代码:

func main() {
    if err := run(); err != nil {
        fmt.Fprintf(os.Stderr, "error: %v\n", err)
        os.Exit(1) //当执行此行时, run()早已执行完退出,其中defer早已执行完;但与os.Exit同一上下文的代码中就不要用defer了, 因为会被中断,不再执行。
    }
}


func run() error {
    err := something()
    if err != nil {
        return err
    }
    // etc, 这是程序用defer清理资源的最后一条防线。
}

参考链接:

http://stackoverflow.com/questions/18963984/exit-with-error-code-in-go

http://stackoverflow.com/questions/28472922/when-to-use-os-exit-and-panic-golang

注意: 此文章只是我个人笔记, 如有错漏,请一定指正, 共同学习, 我的邮箱: htyu_0203_39@sina.com



有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:htyu_0203_39

查看原文:go语言 golang defer 关注点

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

3692 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传