根据这里的帖子http://go-database-sql.org/modifying.html,没有延迟stmt.close()。但是,sql包中有一个stmt.close()API。我似乎无法找到有关在使用预准备语句时是否有必要推迟关闭stmt的信息。因此,问题 - 当我在golang中使用预准备语句时,我是否总是需要推迟stmt.close()?
答案 0 :(得分:2)
使用defer
不是要求,它是便利,它提供安全。重要的是,如果你创建/准备一个语句(它在内部使用一些资源并且也可能在数据库服务器本身中使用资源),那么在某个时候,将来某些时候你会调用它的Close()
方法以便释放由它分配的资源。
即使您的函数突然结束(例如,您有一个早期的return
语句,或者即使您的函数发生混乱),也会执行延迟函数,因此使用defer
关闭资源可以确保代码安全不泄漏资源和/或记忆。
请注意,defer
仅在周围函数返回时运行。可能存在以前可能或甚至适当地关闭语句,而不是等到周围函数返回的情况。一个很好的例子可能是,如果你有一个for
循环进行多次迭代,你不希望每次迭代中创建的所有语句都保留资源,直到for
循环完成。在这种情况下,建议在下一次迭代开始之前关闭资源。在这种情况下,您只需编写一个stmt.Close()
而不是defer stmt.Close()
,因为后者只有在函数返回时才会立即关闭该语句。
另请注意,将循环的主体“外包”到单独的函数中也可以在单独的函数中使用defer
,其中延迟关闭将在下一次迭代开始之前发生。这个变体可能是你在循环体中使用匿名函数(函数文字),你也有机会使用defer
,例如:
for _, v := range values {
func() {
stmt, err := db.Prepare("INSERT INTO users(name) VALUES(?)")
if err != nil {
// handle error
return
}
defer stmt.Close()
// Use stmt...
}()
}