推迟到功能之外

问题描述

我使用的常见模式是:

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()
   ...
}