我可以使用指向“错误”的指针来捕获返回错误吗?

时间:2019-05-30 17:03:12

标签: go

我正在编写一些事务开始/提交/回滚功能,并且我想配对该块以防止忘记提交

我这样写:

std::enable_if

它可以工作,但是它使用“指向接口的指针”,我找不到有关指向接口的指针的规范。

因此,我不确定此代码是否还可以。你能给些建议吗?


感谢teyzer和Corey Ogburn,这是我的固定解决方案:


func (foo *Foo) Bar() (err error) {

  foo.Begin()
  defer foo.End(&err)

  //some business code

  return
}

func (foo *Foo) End(eptr *error) {
  // if recover
  if r := recover(); r != nil {
    debug.PrintStack()
    *eptr = r.(error)
  }

  var err = *eptr
  if err != nil {
    foo.Rollback()
  } else {
    foo.Commit()
  }
}

2 个答案:

答案 0 :(得分:3)

到达defer时,将立即评估延迟函数的参数。这就是为什么如果推迟End本身就必须使用指针的原因。

您可以使用闭包。您的Bar()函数如下所示:


func (foo *Foo) Bar() (err error) {
    foo.Begin()
    defer func() { foo.End(err) }()
    //some business code
    return
}

一旦执行了延迟的闭包,就会计算err的值。

如果您不习惯使用错误返回,那么在Go中使用panic and recovery是更惯用的方式来处理需要回滚的错误(建议使用Corey Ogburn)。

答案 1 :(得分:0)

通常的方法是使用recover()来捕获任何panic。您所拥有的与该方法非常相似。 Check out the Go wiki about Panic and Recover

func (foo *Foo) Bar() (err error) {

  foo.Begin()
  defer foo.End()

  //some business code
  err = fmt.Errorf("oh no, an error!") // set error so that Bar returns it even though it's caught
  panic(err)

  return
}

func (foo *Foo) End() {
  err := recover()
  if err != nil {
    foo.Rollback()
  } else {
    foo.Commit()
  }
}

https://play.golang.org/p/m_kpT5xtwe2