go特性-defer
2024-10-18 17:03:39
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
最新文章
- 您的项目引用了最新实体框架;但是,找不到数据链接所需的与版本兼容的实体框架数据库 EF6使用Mysql的技巧
- SQLServer2005利用维护计划自动备份数据库
- oracle 创建同义词
- js将人民币金额转换为大写
- 转:12C CDB and pdb with sql developer
- 酷炫的方块状散点3D
- tomact配置域名和端口直接访问网站
- MySql技术内幕之MySQL入门(2)
- 第一篇:操纵MySQL数据库(1) - 基于MySQLdb库
- HTTP协议与TCP/IP协议
- Mysql优化之索引和字段
- 浏览器输入URL后,HTTP请求返回的完整过程
- 【Centos】Postgresql连接测试(Perl和Ruby)
- python基础之迭代器与生成器
- JVM内存区域的划分(内存结构或者内存模型)
- 译: 3. Axis2快速入门指南
- Spring Boot 入门搭建
- 回文树练习 Part1
- (转)<;Unity3D>;Unity3D在android下调试
- Windows使用filezilla搭建FTP服务器
热门文章
- Gym102012G Rikka with Intersections of Paths
- 从原生web组件到框架组件源码(二)
- Jmeter 用户定义的变量的使用
- Typora + picgo + sm.ms 图床设置笔记
- 25类Android常用开源框架
- 【转载】VirtualBox 扩展增强包安装
- 论文解读 - Relational Pooling for Graph Representations
- itextpdf freemarker渲染
- 2. RDD(弹性分布式数据集Resilient Distributed dataset)
- tcp 客户端 synack的接收 以及 相互connect