defer和fmt.Println

tyonc · 2022-02-27 02:55:13 · 941 次点击 · 大约8小时之前 开始浏览    置顶
这是一个创建于 2022-02-27 02:55:13 的主题,其中的信息可能已经有所发展或是发生改变。

求解为啥defer输出的不是最终值?

package main
import "fmt"
func main() {
    var i = new(int)
    defer func(i *int) {
        fmt.Println("3:", *i)
    }(i)
    defer fmt.Println("2:", *i)
    *i++
    fmt.Println("1:", *i)
}
//1: 1
//2: 0
//3: 1

我猜应该是和println接收的interface有关,但是不是很肯定和原因是什么?谢谢了。


有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

941 次点击  
加入收藏 微博
4 回复  |  直到 2022-03-01 15:56:51
tyonc
tyonc · #1 · 3年之前

打印指针。

func main() {
    var i = new(int)
    defer func(i *int) {
        fmt.Printf("3:%p,%v\n", i, *i)
    }(i)
    defer fmt.Printf("2:%p,%v\n", i, *i)
    *i++
    fmt.Printf("1:%p,%v\n", i, *i)
}
//1:0x1400001c0a0,1
//2:0x1400001c0a0,0
//3:0x1400001c0a0,1
DKLuck
DKLuck · #2 · 3年之前

defer 栈结构, 3闭包 ,2.不是很清楚,做了自己个断点看看源码吧。 有没有大佬来解?

func main() { var i = new(int)

*i = 5
defer func(i *int) {
    fmt.Printf("3:%p,%v\n", i, *i)
}(i)
*i = 500
defer fmt.Printf("2:%p,%v\n", i, *i)

*i = 50
/*defer func() {
    //fmt.Println(i, *i)
    fmt.Printf("2:%p,%v\n", i, *i)
}()*/

*i++
fmt.Printf("1:%p,%v\n", i, *i)

}

xwszt
xwszt · #3 · 3年之前

defer你可以把它理解为一个栈,先进后出。进栈的是什么,出栈的就是什么

defer func(i *int) {
    fmt.Printf("3:%p,%v\n", i, *i)
}(i)

这里匿名函数的参数是变量i的指针地址,打印的是指针地址存放的值,最后变量i的值是1,那么这里输出的也是1

defer fmt.Printf("2:%p,%v\n", i, *i)

这里压入栈的变量i的值是0,指针地址没有变化,所以输出的就是0

golang传的都是值拷贝,要么是拷贝指针的地址,要么是拷贝变量的值。(通常函数内部不会改变变量的值包括指针的地址,除非使用了unsafe包里的方法改变了指针的地址)

dagongrenzzZ
dagongrenzzZ · #4 · 3年之前

延迟的是函数执行,defer声明时参数就计算确定了

添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传