您的位置:首页 > 编程语言 > Go语言

go语言 golang defer 关注点

2016-03-06 09:47 375 查看
大家都了解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
                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息