在 golang 中管理资源所有权的正确方法是什么?假设我有以下内容:
db, err := sql.Open("mysql", "role@/test_db")
am := NewResourceManager(db)
am.DoWork()
db.Close()
总是让调用函数维护关闭资源的所有权和责任是典型的吗?这对我来说有点奇怪,因为关闭后,仍然保留引用,如果我或其他人稍后不小心,am可以尝试使用(我想这是延迟的情况;但是,如果我想将 ResourceManager 传回)从这个块开始,我如何正确推迟文件的关闭?我实际上希望它在这个块完成执行时保持打开状态)。我发现在其他语言中,我经常希望允许实例管理资源,然后在调用析构函数时清理它,就像这个玩具 python 示例:dbam
class Writer():
def __init__(self, filename):
self.f = open(filename, 'w+')
def __del__(self):
self.f.close()
def write(value):
self.f.write(value)
不幸的是,golang 中没有析构函数。除了这样的事情之外,我不确定如何在 go 中做到这一点:
type ResourceManager interface {
DoWork()
// Close() ?
}
type resourceManager struct {
db *sql.DB
}
func NewResourceManager(db *sql.DB) ResourceManager {
return &resourceManager{db}
}
db, err := sql.Open("mysql", "role@/test_db")
am := NewResourceManager(db)
am.DoWork()
am.Close() // using method shortening
但这似乎不太透明,而且我不确定如何传达 ResourceManager 现在也需要 Close() 的信息。我发现这是一个常见的绊脚石,即我还想要一个保存 gRPC 客户端连接的资源管理器,如果这些类型的资源不是由资源管理对象管理的,那么我的主要功能似乎是充斥着大量的资源管理,即打开和关闭。例如,我可以想象一种情况,我不想main知道有关该对象及其资源的任何信息:
...
func NewResourceManager() ResourceManager {
db, err := sql.Open("mysql", "role@/test_db")
return &resourceManager{db}
}
...
// main elsewhere
am := NewResourceManager()
am.DoWork()
温温酱
相关分类