[go语言]使用defer和有名返回值,实现初始化失败的自动回滚
var err errorerr = init_a()if err != nil {
}return errerr = init_b()if err != nil {
uninit_a()
}return err
err = init_c()
if err != nil {
uninit_b()uninit_a()return err}
err = init_d()
if err != nil {
uninit_c()uninit_b()uninit_a()return err}
return nil
var err errorerr = init_a()if err != nil {
}goto _errerr = init_b()if err != nil {
goto _ua}
err = init_c()
if err != nil {
goto _ub}
err = init_d()
if err != nil {
_uc:goto _uc}
uninit_c()_ub:
uninit_b()
uninit_a()
_exit:return err
return nil
- label太多,看的眼花
- 使用goto,执行流程一下子跳走了,导致思维中断和跳跃
- 变量的初始化全部要放到函数的开始位置,不能放在使用它的地方,不然会编译报错“jumps over declaration”。
inits := []func() error {init_a, init_b, init_c, init_d}uinits := []func() error {uninit_a, uninit_b, uninit_c, uninit_d}for i := 0; i < len(inits); i++ {
err := inits[i]()if err != nil {
for j := i - 1; j >= 0; j-- {
}uninit[j]()return err}
}return nil
rollback := func(uninit func()) {
if err != nil {
uninit()
}
}err = init_a()if err != nil {
}return err
defer rollback(uninit_a)
err = init_b()
if err != nil {
return err}
defer rollback(uninit_b)
err = init_c()
if err != nil {
return err
}
deferrollback(uninit_c)
}return init_d()
- 绝大多数情况下反初始化函数的参数签名都是一样的
- 即使个别不一样,在defer的时候也可以用闭包封装一下,没有什么负担。例如:
defer rollback(func(){uninit_b(100)})
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。