go defer注意点,很容易出错的!!!
1:defer是在return之前执行的 函数返回的过程是这样的:先给返回值赋值,然后调用defer表达式,最后才是返回到调用函数中
返回值 = xxx
调用defer函数
空的return
func f() (result int) {
result = 0 //return语句不是一条原子调用,return xxx其实是赋值+ret指令
func() { //defer被插入到return之前执行,也就是赋返回值和ret指令之间
result++
}()
return
}
func f() (r int) {
t := 5
r = t //赋值指令
func() { //defer被插入到赋值与返回之间执行,这个例子中返回值r没被修改过
t = t + 5
}
return //空的return指令
}
2:有名返回值和匿名返回值的问题
匿名返回值是在 return 执行时被声明,有名返回值则是在函数声明的同时被声明,因此在 defer 语句中只能访问有名返回值,而不能直接访问匿名返回值
此方法返回的是2 而不是1 之前在这困扰了好久,就是没弄明白对匿名返回值的函数是无法修改该返回值的,匿名返回值相当于又重新赋值了一个新的变量
func det2() int {
result := 2
println(&result)
defer func(result *int) {
println("det2")
*result = 1
println(*result)
}(&result)#所以对result无论如何修改都无法改变返回值的内容
#可变形为
匿名变量 = result
return 匿名变量
}
相反的 defer修饰的有名返回值的函数可以修改最后的返回值内容
func b() (i int) { defer func() { i++ fmt.Println("b defer2:", i) // 打印结果为 b defer2: 2 }() defer func() { i++ fmt.Println("b defer1:", i) // 打印结果为 b defer1: 1 }() return i // 或者直接 return 效果相同} func b() { defer func() { i++ fmt.Println("b defer2:", i) // 打印结果为 b defer2: 2 }() defer func() { i++ fmt.Println("b defer1:", i) // 打印结果为 b defer1: 1 }() return i // 或者直接 return 效果相同} 此时返回值为 03:defer 调用的函数参数的值在 defer 定义时就确定了, 而 defer 函数内部所使用的变量的值需要在这个函数运行时才确定func f1() (r int) {
r = 1 defer func() { r++ fmt.Println(" r value = ",r) }() r = 2 return}参考:https://www.jb51.net/article/127130.htm
go defer注意点,很容易出错的!!!的更多相关文章
- 使用JSONArray.fromObject转化list时,如果有集合属性,很容易出错,此刻把集合属性过滤掉便可
使用JSONArray.fromObject转化list时,如果有集合属性,很容易出错,此刻把集合属性过滤掉便可
- github上的QT源码,必要的时候还是应该看一下,仅凭猜测很容易出错
QCoreApplication::processEvents 他处理的时候拿的是current不是qAppqApp的话,才是和主线程密切相关的 一直觉得QT源码复杂,有点怕,所以没怎么看 我也看不懂 ...
- 使用jquery方法的时候,要注意对象是哪个,否则很容易出错
<!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cs ...
- async与defer
<script>元素的几种常见属性: async 异步加载,立即下载,不应妨碍页面其他操作,标记为 async 的异步脚本并不保证按照指定的先后顺序执行,因此异步脚本不应该在加载期间修改 ...
- 拒绝滥用golang defer机制
原文链接 : http://www.bugclosed.com/post/17 defer机制 go语言中的defer提供了在函数返回前执行操作的机制,在需要资源回收的场景非常方便易用(比如文件关闭, ...
- Javascript 中我很想说说的 this
this是每一个想要深入学习Javascript的人必过的一关,我为this看过很多书查过很多资料,虽然对this有了一定的了解并且也经常使用this,但是如果有人问我 this是什么呀? 我依旧不 ...
- list如何remove 特别容易出错
java中对list进行操作很频繁,特别是进行list启遍历,这些操作我们都会,也很熟悉,但是对java中list进行删除元素,remove list中的元素就不怎么熟悉了吧,可以说很陌生,是实际操作 ...
- sp_helptext输出错行问题解决
相信,大家对sp_helptext存储过程一定不陌生,它可以帮你快速获取存储过程等对象的定义.但它有一个致命的缺点就是:每行最多返回255个nvarchar类型的字符,假如有一个编写不规范的存储过程, ...
- golang学习 ---defer语句
golang语言defer特性详解 defer语句是go语言提供的一种用于注册延迟调用的机制,它可以让函数在当前函数执行完毕后执行,是go语言中一种很有用的特性.由于它使用起来简单又方便,所以深得go ...
随机推荐
- 多源最短路——Floyd算法
Floyd算法 问题的提出:已知一个有向网(或者无向网),对每一对定点vi!=vj,要求求出vi与vj之间的最短路径和最短路径的长度. 解决该问题有以下两种方法: (1)轮流以每一个定点为源点,重复执 ...
- 互评Alpha版本——基于spec评论作品
组名:可以低头,但没必要 组长:付佳 组员:张俊余 李文涛 孙赛佳 田良 于洋 刘欣 段晓睿 一.二次元梦之队----I DO 在测评该项目时,我们组索要了该组的apk程序,安装之后我就开 ...
- mysql---时间类型详解
mysql 日期类型 mysql 日期类型 · DATE (适用于"出生日期"等只需要年月日数据的日期字段) 日期.支持的范围为'1000-01-01'到'9999-12- ...
- jQuery之基本选择器
1. 是什么? - 有特定格式的字符串2. 作用 - 用来查找特定页面元素3. 基本选择器 - #id : id选择器 - element : 元素选择器 - .class : 属性选择器 - * : ...
- 【第三周】每周psp
代码累计 300+575+475=1250 随笔字数 1700+3000+3785=8485 知识点 Cppunit框架 Ui设计 Scrum站立会议 燃尽图(好像没燃起来) 博客写作技能 本周主要是 ...
- HDU 2156 分数矩阵
http://acm.hdu.edu.cn/showproblem.php?pid=2156 Problem Description 我们定义如下矩阵:1/1 1/2 1/31/2 1/1 1/21/ ...
- J2EE十三种技术规范介绍
J2EE的十三个技术规范 J2EE体系结构 一.JDBC:Java Data Base Connectivity,数据库连接 我们大家对微软公司的ODBC数据库访问接口比较熟悉,而在Java中创建数据 ...
- postman 断言学习
请求 url :https://www.v2ex.com/api/nodes/show.json?name=python get请求 postman发起请求并做断言 断言: tests["B ...
- BZOJ 1228 E&G(sg函数+找规律)
把一对石子堆看出一个子游戏.打出子游戏的sg表找规律.. 这个规律我是一定找不出来的... 对于i,j,如果 (i-1)%pow(2,k+1) < pow(2,k) (j-1)%pow(2,k+ ...
- 【bzoj3125】CITY 插头dp
题目描述 给出一个n*m的矩阵,某些格子不能通过,某些格子只能上下通过或左右通过.求经过所有非不能通过格子的哈密顿回路条数. 输入 第一行有两个数N, M表示地图被分割成N*M个块,接下来有N行,每行 ...