go defer xx.Close()位置问题小记
go代码中经常用到申请资源:譬如tcp连接、譬如mysql的连接池连接等,这种通常会在申请对应资源之后(这里资源用conn表示)使用defer conn.Close()这样在程序退出时进行关闭
但是通常申请资源的时候还会带着一个err,形如
conn, err := GetConn()
defer conn.Close()
if err != nil {
log.Fatal(err)
return
}
通常会对err进行判断,以及使用defer xx.Close()
那么它们的顺序应该是怎么样呢??
在这种情况下,应该是先判断err是否存在,然后再进行调用defer xx.Close()
假如GetConn()中出现故障,有两种情况,一申请出conn,但其不可用;另一种则是未申请到conn,通常conn获得的返回值是nil
当然,它们的err都不会是nil
如果是先执行defer xx.Close()的话,在第二种情况下,可能会在conn为nil的时候依然执行了conn.Close(),假如这个Close()函数保护不够充分,则容易会产生panic
故建议:
- 先对err进行判断,如果err不是nil,那么肯定已经有错误产生了,先处理错误
- 若err是nil,那么conn也是可用的,这时候声明defer conn.Close()便不会有什么问题了