这篇文章主要介绍“go defer的作用是什么”,在日常操作中,相信很多人在go defer的作用是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”go defer的作用是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

成都创新互联公司专注于企业全网营销推广、网站重做改版、五莲网站定制设计、自适应品牌网站建设、H5网站设计、商城网站建设、集团公司官网建设、外贸网站制作、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为五莲等各大城市提供网站开发制作服务。
defer 关键字
很多现代的编程语言中都有 defer 关键字,Go 语言的 defer 会在当前函数返回前执行传入的函数,它会经常被用于关闭文件描述符、关闭数据库连接以及解锁资源。
使用 defer 的最常见场景是在函数调用结束后完成一些收尾工作,例如在 defer 中回滚数据库的事务:
func InsertObj() error {
   //获取一个数据库session
   db := db.GetDB().Begin()
   defer db.Rollback()
   
   //do someting
   err := db.Insert()
   
   if err != nil{
    return err
   }
   
   return db.Commit().Error
}
在使用数据库事务时,我们可以使用上面的代码在创建事务后就立刻调用 Rollback 保证事务一定会回滚。哪怕事务真的执行成功了,那么调用 Commit() 之后再执行 Rollback() 也不会影响已经提交的事务。
defer的特性
- defer的调用时机以及多次调用- defer时执行顺序
- defer使用传值的方式传递参数时会进行预计算,导致不符合预期的结果
func main() {
	defer fmt.Println(0)
       defer fmt.Println(1)
       defer fmt.Println(2)
       defer fmt.Println(3)
       	
}
上面的代码输出:
3
2
1
0
那么defer的执行顺序就是先进后出
func main() {
   {
       defer fmt.Println("defer runs")
       fmt.Println("block ends")
   }
   
   fmt.Println("main ends")
}
输出:
block ends
main ends
defer runs
可以看出defer不是在退出代码块的作用域时执行的,它只会在当前函数和方法返回之前被调用
预计算
func main() {
	startedAt := time.Now()
	defer fmt.Println(time.Since(startedAt))
	time.Sleep(time.Second)
}
输出:
0s
调用 defer 关键字会立刻拷贝函数中引用的外部参数,所以 time.Since(startedAt) 的结果不是在 main 函数退出之前计算的,而是在 defer 关键字调用时计算的,最终导致上述代码输出 0s。
那么如果要解决这个问题可以改写代码
func main() {
	startedAt := time.Now()
	defer func() { fmt.Println(time.Since(startedAt)) }()
	time.Sleep(time.Second)
}
输出:
1s
虽然调用 defer 关键字时也使用值传递,但是因为拷贝的是函数指针
defer 常用的案例
捕获异常和崩溃日志:
func process() error {
	defer func() {
               //防止意外之外的错误导致程序崩溃
		if err := recover(); err != nil {
                       //崩溃日志的捕获
			core.LogPnc.Errorf("panic : %v", err)
			core.LogPnc.Errorf("%s", string(debug.Stack()))
		}
	}()
       //do something
	err := obj.CALL(parseYML)
	if err != nil {
		return err
	}
	return nil
}
释放锁:
func runTask() {
       //上锁
	c.lk.Lock()
       //释放锁
	defer c.lk.Unlock()
	//do something
}
在函数返回之前进行业务操作
func (c *ProcessEngine) Process(ph *ProcessHook) {
	defer func() {
		c.lk.Lock()
               //逻辑处理
		c.running--
		c.lk.Unlock()
	}()
       //do something
}到此,关于“go defer的作用是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!
当前标题:godefer的作用是什么
当前路径:http://www.scyingshan.cn/article/ghghcj.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 