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行琐碎的代码时,比如说,我在几个不同的地方需要相同的四个资源。如果您发现自己需要在代码中多次打开和关闭同一组多个资源,这听起来像是一个严重的设计/架构问题。不,打开/关闭资源是正常的。必须在代码中的多个位置打开/关闭同一组资源是一个设计问题。这是有道理的,但对于回调签名来说似乎非常特殊。编辑为包含另一个方法。