golang for循环种遍历defer

defer需求分析

golang中几乎所有涉及对数据库的操作都要在回滚操作时用到defer,而当涉及到批量创建/删除操作的回滚时,就要在for循环内使用defer,虽不推荐使用,但这可以在遍历其中一条数据失败时即可回滚止损

func saveDB() error {
	ips := []string{"192.168.1.1","192.168.1.2"}
	for _, ip := range ips {
			if err := db.create(ip); err != nil {
				errInfo := fmt.Sprintf("save ip to db error %+v", err)
				logCtx.Errorf(errInfo)
				return errors.New(errInfo)
			}
			defer func(ip string) {
				if err != nil {
					_, errTmp := db.delete(ip)
					if errTmp != nil {
						errInfo := fmt.Sprintf("delete ip error %v", errTmp)
						logCtx.Errorf(errInfo)
					}
				}
			}(ip)
		}
	}

注意点:每一条for循环遍历时,defer中第一个判断条件是err!=nil,这个err是执行存入数据库的err,而我们执行回滚里将创建失败的数据删除,此时的errTmp必须与err名字错开,否则若执行回滚内的操作失败,全局的err还是会进入defer,进入死循环状态

defer坑

1、defer是先进后出
2、压入defer中的数据不会随后续代码中更改而更改(比如定义i=0,存入defer后续执行i++,但最后defer中的i值仍然是 0)
3、defer可以修改返回值,如果defer中的是i++,最后返回值的i如果是1,执行完defer后,返回值变成2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值