Go 服从于职能之外
我使用的一种常见模式是:Go 服从于职能之外,go,deferred,Go,Deferred,我使用的一种常见模式是: resource.open() defer resource.close() 有时检查中间的错误,这会导致: err := resource.open() if err != nil{ //do error stuff and return } defer resource.close() 有时,我需要一行中的多个打开/关闭资源,导致前5行的变化会一行接一行地重复。这种变化可能会在我的代码中逐字重复数次(我需要所有相同的资源) 将所有这些都封装在一个函数中
resource.open()
defer resource.close()
有时检查中间的错误,这会导致:
err := resource.open()
if err != nil{
//do error stuff and return
}
defer resource.close()
有时,我需要一行中的多个打开/关闭资源,导致前5行的变化会一行接一行地重复。这种变化可能会在我的代码中逐字重复数次(我需要所有相同的资源)
将所有这些都封装在一个函数中会很好。但是,这样做会在函数调用结束后立即关闭资源。有什么办法可以解决这个问题吗?要么推迟到调用堆栈的“升级”阶段,要么采取其他方式?一种方法是使用带有回调的“初始值设定项”函数:
func WithResources(f func(Resource1, Resource2)) {
r1:=NewResource1()
defer r1.Close()
r2:=NewResource2()
defer r2.Close()
f(r1,r2)
}
func F() {
WithResources(func(r1 Resource1, r2 Resource2) {
// Use r1, r2
})
}
函数f
的签名取决于具体的用例
另一种方法是对资源集使用结构:
type Resources struct {
R1 Resource1
R2 Resource2
...
}
func NewResources() *Resources {
r:=&Resources{}
r.R1=NewR1()
r.R2=NewR2()
return r
}
func (r *Resources) Close() {
r.R1.Close()
r.R2.Close()
}
func f() {
r:=NewResources()
defer r.Close()
...
}
您不能调用另一个函数来推迟事情。您可以使用一个函数来初始化资源并延迟关闭它们,然后调用作为这些资源的参数传入的另一个函数。
defer
在调用它的函数返回句点时运行。“在围棋中,重复5行琐碎的台词是非常常见的。”阿德里安·特鲁尔。抱怨这是另一个话题:)我的问题是当我重复同样的20行琐碎的代码时,比如说,我在几个不同的地方需要相同的四个资源。如果您发现自己需要在代码中多次打开和关闭同一组多个资源,这听起来像是一个严重的设计/架构问题。不,打开/关闭资源是正常的。必须在代码中的多个位置打开/关闭同一组资源是一个设计问题。这是有道理的,但对于回调签名来说似乎非常特殊。编辑为包含另一个方法。