前端仔有点学不明白 golang 的 defer

zhengfan2016 · 2025-4-1 17:37:03 · 2421 次点击

背景:这个地方的 test-1 题 https://golang.dbwu.tech/traps/defer_exam/

如下 test-1 题,使用具名返回值,defer 就能修改 t 的值

package main

func foo(n int) (t int) {
	t = n
	defer func() {
		t += 3
	}()
	return t
}

func main() {
	println(foo(1))
}

但是我不使用具名,就算我把 t 移到最外层的作用域,defer 也改变不了 t 的值,我试着不在 defer 作用域内,就可以修改

package main

var t int

func foo(n int) int {
	t = n
	defer func() {
		t += 3
	}()
	return t
}

func main() {
	println(foo(1))
}

感觉被绕晕了

举报· 2421 次点击
登录 注册 站外分享
22 条回复  
mightybruce 小成 2025-4-1 18:37:39
大家其实都是猜测, 要真深入,直接让 go 生成编译的汇编,直接查看汇编代码就好 https://gocompiler.shizhz.me/10.-golang-bian-yi-qi-han-shu-bian-yi-ji-dao-chu/10.2.1-ssa
coderlxm 小成 2025-4-1 18:36:19
看来还是要多问啊,之前我这里也有疑惑但是实际没有这种写法就没管了。
Liv1Dad 初学 2025-4-1 18:26:27
@wunonglin #2 我代码经常写 defer ,比如打开文件需要 close, 或者回收 chan, 还有数据库事物结束。
Liv1Dad 初学 2025-4-1 18:24:40
很简单啊,defer 放到 一个栈里面。 defer func() { t+=3}() 这个匿名函数 放入到栈中, 等 function 结束时运行。 第一个 函数返回 t, 函数结束后继续执行了 t+=3 。 第二个 函数返回 t 的值,数据结束后继续执行了 t+=3, 此时的 t 和函数返回结果 没有关系。
maxwellz 小成 2025-4-1 18:14:50
@zhengfan2016 #7 貌似和 defer 的特性有关系了,这块太久没看了,忘了
peteretep 初学 2025-4-1 18:09:16
后端仔都不这么写的。不要起步就走犄角旮旯了。没有实际意义的。 这个和 c++考试 i++++ 、 ++i++ 的题目有什么区别吗? defer 只用来释放资源,其他使用正常的程序算法解决。
sardina 小成 2025-4-1 18:07:30
第一个例子 return 是先把返回值存到临时变量里,然后 defer 再修改也改不到临时变量 第一个例子因为返回值有命名,所以 return 是把返回值存到这个命名里里,然后 defer 就可以修改了 总的来说就是 return 先设置返回值 然后再执行 defer ,然后函数返回 https://www.cnblogs.com/saryli/p/11371912.html 可以看这个
zhengfan2016 楼主 小成 2025-4-1 18:06:58
@NessajCN 原来如此
ChrisFreeMan 小成 2025-4-1 18:01:45
@lesismal 看到你也不会我就放心了
123下一页
返回顶部