go语言 golang defer 关注点

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


注意:以上红色文字引自Go语言程序设计,Mark Summerfield; 此文之前版本在此处表述有不严谨之处, 抱歉,修改之!

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值