1:后定义的defer先执行(可以理解为栈的方式)

// 222
// 111
func Test1(t *testing.T) {
defer fmt.Println("111")
defer fmt.Println("222")
}

2:defer定义的函数的参数,在定义的时候已经被赋值了

// defer 函数定义的时候,参数已经被赋值了(参数被捕捉了)

// 输出:
// 第二个defer: 2
// 第一个defer: 1
func Test2(t *testing.T) {
a := 1 // 注意这里,a作为defer函数的参数。defer函数定义的时候,就把a的值确定了
defer fmt.Println("第一个defer: ", a) defer func() {
fmt.Println("第二个defer: ", a)
}() a+=1
}

3:defer函数可以修改具名返回值,但不会修改匿名返回值

/////////////////////////////////////////////////////////
// defer 函数可以修改具名返回值,但是不会修改匿名返回值
// 输出
// fHasName: 2
// fNoName: 1
func fHasName() (val int) {
val = 1
defer func() {
// 因为val是个具名返回值,所以这里对val的操作,会影响到返回值
val += 1
}() return val
}
func fNoName() int {
val := 1
defer func() {
// 这里的操作则不会影响返回值
val += 1
}() return val
}

4:遇到panic的时候,当前协程调用栈已定义的defer将被执行,如果当前协程没有任何一个defer函数内执行了recover,那么执行完所有的defer之后,将会触发panic退出进程

/* 输出
has: 333
err: haha
has: 222
has: 111
*/
func TestHasRecover(t *testing.T) {
defer fmt.Println("has: 111")
defer fmt.Println("has: 222")
defer func() {
if err := recover(); err != nil {
fmt.Println("err:", err)
}
}()
defer fmt.Println("has: 333")
panic("haha")
defer fmt.Println("has: 444")
} /* 输出
has: 333
has: 222
has: 111 panic: haha [recovered]
panic: haha goroutine 19 [running]:
testing.tRunner.func1.1(0x95df20, 0x9b2110)
C:/Go/src/testing/testing.go:1076 +0x310
testing.tRunner.func1(0xc000140480)
C:/Go/src/testing/testing.go:1079 +0x43a
*/
func TestNoRecover(t *testing.T) {
defer fmt.Println("has: 111")
defer fmt.Println("has: 222")
defer fmt.Println("has: 333")
panic("haha")
defer fmt.Println("has: 444")
}

最后来一道总结题,如下代码会输出什么?


import "testing"
import "fmt" func sum(tip string, a int, b int) int {
sum := a + b
fmt.Printf("tip=%s a=%d b=%d sum=%d\n", tip, a, b, sum)
return sum
} func deferSum() {
a := 1
b := 2
defer sum("1tip", a, sum("2tip", a, b))
a = 3
defer func(b int) {
sum("3tip", a, sum("4tip", a, b))
}(a)
b = 4
defer func() {
sum("5tip", a, sum("6tip", a, b))
}()
} func TestDeferSum(t *testing.T) {
deferSum()
}

正确答案如下:

tip=6tip a=3 b=4 sum=7
tip=5tip a=3 b=7 sum=10
tip=4tip a=3 b=3 sum=6
tip=3tip a=3 b=6 sum=9
tip=1tip a=1 b=3 sum=4

最新文章

  1. 您的项目引用了最新实体框架;但是,找不到数据链接所需的与版本兼容的实体框架数据库 EF6使用Mysql的技巧
  2. SQLServer2005利用维护计划自动备份数据库
  3. oracle 创建同义词
  4. js将人民币金额转换为大写
  5. 转:12C CDB and pdb with sql developer
  6. 酷炫的方块状散点3D
  7. tomact配置域名和端口直接访问网站
  8. MySql技术内幕之MySQL入门(2)
  9. 第一篇:操纵MySQL数据库(1) - 基于MySQLdb库
  10. HTTP协议与TCP/IP协议
  11. Mysql优化之索引和字段
  12. 浏览器输入URL后,HTTP请求返回的完整过程
  13. 【Centos】Postgresql连接测试(Perl和Ruby)
  14. python基础之迭代器与生成器
  15. JVM内存区域的划分(内存结构或者内存模型)
  16. 译: 3. Axis2快速入门指南
  17. Spring Boot 入门搭建
  18. 回文树练习 Part1
  19. (转)<Unity3D>Unity3D在android下调试
  20. Windows使用filezilla搭建FTP服务器

热门文章

  1. Gym102012G Rikka with Intersections of Paths
  2. 从原生web组件到框架组件源码(二)
  3. Jmeter 用户定义的变量的使用
  4. Typora + picgo + sm.ms 图床设置笔记
  5. 25类Android常用开源框架
  6. 【转载】VirtualBox 扩展增强包安装
  7. 论文解读 - Relational Pooling for Graph Representations
  8. itextpdf freemarker渲染
  9. 2. RDD(弹性分布式数据集Resilient Distributed dataset)
  10. tcp 客户端 synack的接收 以及 相互connect