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 效果相同
}   
最终返回的结果i为2 ,若果将上述函数变为匿名返回值
 
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 // 或者直接 return 效果相同
}  此时返回值为 0

3: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注意点,很容易出错的!!!的更多相关文章

  1. 使用JSONArray.fromObject转化list时,如果有集合属性,很容易出错,此刻把集合属性过滤掉便可

    使用JSONArray.fromObject转化list时,如果有集合属性,很容易出错,此刻把集合属性过滤掉便可

  2. github上的QT源码,必要的时候还是应该看一下,仅凭猜测很容易出错

    QCoreApplication::processEvents 他处理的时候拿的是current不是qAppqApp的话,才是和主线程密切相关的 一直觉得QT源码复杂,有点怕,所以没怎么看 我也看不懂 ...

  3. 使用jquery方法的时候,要注意对象是哪个,否则很容易出错

    <!DOCTYPE html><html><head><meta charset="utf-8"><title>W3Cs ...

  4. async与defer

    <script>元素的几种常见属性: async  异步加载,立即下载,不应妨碍页面其他操作,标记为 async 的异步脚本并不保证按照指定的先后顺序执行,因此异步脚本不应该在加载期间修改 ...

  5. 拒绝滥用golang defer机制

    原文链接 : http://www.bugclosed.com/post/17 defer机制 go语言中的defer提供了在函数返回前执行操作的机制,在需要资源回收的场景非常方便易用(比如文件关闭, ...

  6. Javascript 中我很想说说的 this

    this是每一个想要深入学习Javascript的人必过的一关,我为this看过很多书查过很多资料,虽然对this有了一定的了解并且也经常使用this,但是如果有人问我  this是什么呀? 我依旧不 ...

  7. list如何remove 特别容易出错

    java中对list进行操作很频繁,特别是进行list启遍历,这些操作我们都会,也很熟悉,但是对java中list进行删除元素,remove list中的元素就不怎么熟悉了吧,可以说很陌生,是实际操作 ...

  8. sp_helptext输出错行问题解决

    相信,大家对sp_helptext存储过程一定不陌生,它可以帮你快速获取存储过程等对象的定义.但它有一个致命的缺点就是:每行最多返回255个nvarchar类型的字符,假如有一个编写不规范的存储过程, ...

  9. golang学习 ---defer语句

    golang语言defer特性详解 defer语句是go语言提供的一种用于注册延迟调用的机制,它可以让函数在当前函数执行完毕后执行,是go语言中一种很有用的特性.由于它使用起来简单又方便,所以深得go ...

随机推荐

  1. centos 系统初始化

    centos 系统初始化 #!/bin/bash # author cfwl create date of 2012-10-21 # blog http://cfwlxf.blog.51cto.com ...

  2. 请教Amazon FBA里面Label Service, Stickerless, Commingled Inventory是什么意思?

    Accept Label Service接受标签服务,选择了以后下面的操作中会有一个让您打印标签的流程,您就可以按照FBA流程提示进行每一步标签服务的操作. Accept Stickless, Com ...

  3. 基于 Agent 的模型入门:Python 实现隔离仿真

    2005 年诺贝尔经济学奖得主托马斯·谢林(Thomas Schelling)在上世纪 70 年代就纽约的人种居住分布得出了著名的 Schelling segregation model,这是一个 A ...

  4. windows64系统下安装 redis服务 (详细)

    Linux下Redis安装链接 :     转到 redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表) ...

  5. [leetcode-914-X of a Kind in a Deck of Cards]

    In a deck of cards, each card has an integer written on it. Return true if and only if you can choos ...

  6. python---json.dumps 与 json.loads /json.dump 和json.load区别

    json.dumps 是将python的数据类型进行json的编码,生成json格式的数据,举例json_data = json.dumps(str)  str为python的字符串类型数据,生成的j ...

  7. zend安装及破解

    Zend下载 https://pan.baidu.com/s/1fCfUQ0j7dxEtOzbNnsgODg 破解: 1.打开dmg文件安装,将Zend Studio拖拽至applications进行 ...

  8. Python:文件操作总结1——文件基本操作

    一.文件的操作流程 1.打开文件,得到文件句柄并赋值给一个变量 2.通过句柄对文件进行操作 3.关闭文件 二.文件的打开与关闭 A.文件的打开——open函数 语法:open(file[,mode[, ...

  9. Python:模块学习——sys模块

    sys模块常见函数和变量 sys.argv:命令行参数,实现从程序外部向程序传递参数 [注]:(1) sys.argv[0] 表示代码本身的文件路径 (2)sys.argv是一个元组,可以用[ ]提取 ...

  10. 博弈---尼姆博奕(Nimm Game)(重点)

    尼姆博奕(Nimm Game):有三堆各若干个物品,两个人轮流从某一堆取任意多的 物品,规定每次至少取一个,多者不限,最后取光者得胜. 这种情况最有意思,它与二进制有密切关系,我们用(a,b,c)表示 ...