golang defer原理


这篇文章是系列文章的第一篇,系列文章主要包括:

  1. golang defer的原理
  2. golang panic和recover()函数的原理(包括golang对于错误处理方式)
  3. defer性能损耗的讨论以及最重要的应用场景
  4. defer在golang 1.13 上的性能

defer的特性

首先,我们通过一些实际的例子来看 defer 的特性。

1. 延迟调用

package main

import (
	"fmt"
	"log"
)

func main() {
   
	defer log.Println("defer sim lou")
	fmt.Println("ending")
}

输出结果:

ending
2019/10/22 22:50:32 defer sim lou

可以看到 defer 定义的函数是在 main 函数逻辑执行完了之后才执行的,也就是延迟调用。

2. 后进先出

package main

import (
	"log"
	"strconv"
)

func main() {
   
	for i := 1; i <= 6; i++ {
   
		defer log.Println("defer sim lou-" + strconv.Itoa(i) + ".")
	}
	log.Println("ending.")
}

输出结果:

2019/10/22 22:56:37 ending.
2019/10/22 22:56:37 defer sim lou-6.
2019/10/22 22:56:37 defer sim lou-5.
2019/10/22 22:56:37 defer sim lou-4.
2019/10/22 22:56:37 defer sim lou-3.
2019/10/22 22:56:37 defer sim lou-2.
2019/10/22 22:56:37 defer sim lou-1.

根据输出可以看到,defer 函数的执行顺序是 LIFO,也就是后进先出的。

3. defer 作用域

package main

import (
	"log"
)

func main() {
   
	func() {
   
		defer log.Println("defer sim lou.")
	}()
	log.Println("main.ending.")
}

输出结果是:

2019/10/22 22:58:59 defer sim lou.
2019/10/22 22:58:59 main.ending.

可以看到 defer 的作用于是函数级别的, 也就是defer 生效在 defer 定义所在的函数栈。

4. 异常处理

package main

import (
	"log"
)

func main() {
   
	defer func() {
   
		if e := recover(); e != nil {
   
			log.Println("defer sim lou.")
		}
	}()
	panic("throw panic")
}

输出结果是:

2019/10/23 23:45:28 defer sim lou.

性能测试

defer 不是免费的午餐,任何一次的 defer 都存在性能问题,这样一个简单的性能对比:

基于go 1.13:

package main

import (
	"sync"
	"testing"
)

var lock sync.Mutex

func NoDefer() {
   
	lock.Lock()
	lock.Unlock()
}
func Defer(
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值