英文:
Break chaining methods using sync package
问题
上次我发现我不需要检查变量是否为nil来创建单例服务,而是可以使用sync.Once来实现相同的结果,下面是一个示例:
// 替代
var instance Instance
func NewInstance() {
    if instance == nil {
        instance = Instance{}
    }
    return instance
}
// 可以这样做
var (
    once sync.Once
    instance Instance
)
func NewInstance() {
    once.Do(func() {
        instance = Instance{}
    })
    return instance
}
我的问题是:
我可以使用sync包来打破链式规则并返回错误吗?
期望的结果:
var (
    breakChain sync.SomethingToBreakChain
    err error
)
type s struct {}
func (s *s) F1() s {
    err = service1.DoSomething()
    // sync 做一些事情
    return s
}
func (s *s) F2() s {
    err = service2.DoSomething()
    // sync 做一些事情
    return s
}
func (s *s) F3() s {
    err = service3.DoSomething()
    // sync 做一些事情
    return s
}
func (s *s) GetError() {
    return err
}
func New() {
    s := s{}
    s.F1(). // 如果发生错误,保存到`err`变量,并在此处中断链式调用,阻止执行`F2`和`F3`
      F2(). // 如果发生错误,保存到`err`变量,并在此处中断链式调用,阻止执行`F3`
      F3() // 如果发生错误,保存到`err`变量并返回
    err := s.GetError()
    // 处理`err`
}
英文:
Last time I found out I didn't have to check if variable is nil to make singleton service but I can use sync.Once to achieve the same result, example below:
// instead of
var instance Instance
func NewInstance() {
    if instance == nil {
        instance = Instance{}
    }
    return instance
}
// can do this
var (
    once sync.Once
    instance Instance
)
func NewInstance() {
    once.Do(func() {
        instance = Instance{}
    })
    return instance
}
My question is:
Can I use sync package to break chaining rules and return error?
Desired result:
var (
    breakChain sync.SomethingToBreakChain
    err error
)
type s struct {}
func (s *s) F1() s {
    err = service1.DoSomething()
    // sync do something
    return s
}
func (s *s) F2() s {
    err = service2.DoSomething()
    // sync do something
    return s
}
func (s *s) F3() s {
    err = service3.DoSomething()
    // sync do something
    return s
}
func (s *s) GetError() {
    return err
}
func New() {
    s := s{}
    s.F1(). // if error save to `err` variable and break chain here prevent `F2` and `F3` to execute
      F2(). // if error save to `err` variable and break chain here prevent `F3`  to execute
      F3() // if error save to `err` to return
    err := s.GetError()
    // do something with `err`
}
答案1
得分: 3
如果你想实现这样的链式调用,可以考虑在接收器本身保存错误,并在每个操作中进行检查:
type s struct {
  e error
}
func (s *s) F1() *s {
  if s.e != nil {
    return s
  }
  // 做一些事情
  if err := doThings(); err != nil {
     s.e = err
  }
  return s
}
...
否则,没有机制可以阻止在链中调用其他方法。
英文:
If you want to implement a chain like that, you might consider saving the error in the receiver itself and checking in every action:
type s struct {
  e error
}
func (s *s) F1() *s {
  if s.e!=nil {
    return s
  }
  // Do things
  if err:=doThings(); err!=nil {
     s.e=err
  }
  return s
}
...
Otherwise, there are no mechanisms to prevent calling other methods in the chain.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论