首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >golang中defer的小坑

golang中defer的小坑

原创
作者头像
浩瀚星河
发布2025-07-07 23:36:50
发布2025-07-07 23:36:50
840
举报
文章被收录于专栏:golanggolang

我们都知道,defer往往在函数的最后执行,遵循先进后出原则,在return函数写入返回值后执行,而且传入的形参会立即读入,后续修改对其无影响

Go 函数返回过程完整流程

当一个函数执行到 return 语句时,执行顺序是

  1. 计算 return 后的表达式(如果有的话),将结果赋值给返回值;
  2. 执行所有的 defer 语句(按照后进先出 LIFO 的顺序);
  3. 函数真正返回(携带返回值)

下面来看这三个案例

代码语言:go
复制
package main

import "fmt"

func Func1() int {
	a := 0
	defer func() {
		a++
	}()
	return a
}

func Func2() (a int) {
	a = 0
	defer func() {
		a++
	}()
	return
}

func Func3() *int {
	a := new(int)
	*a = 0
	defer func() {
		*a++
	}()
	return a
}

func main() {
	fmt.Println(Func1())
	fmt.Println(Func2())
	fmt.Println(*Func3())
}

输出结果为

代码语言:bash
复制
0 1 1

案例分析

这三个究竟有什么区别呢?

案例一:

  1. 首先,我们获得a的值0,然后会重新赋值一份给临时的返回槽(slot)当中
  2. 然后,调用defer,修改局部变量a为1,但是a已被copy一份到返回槽,所以重新赋值没有用
  3. 返回0

案例二:

  1. 首先,我们获得a的值0,然后会重新赋值一份给临时的返回槽(slot)当中
  2. 然后defer修改了引用类型a的值
  3. 返回1

案例三:

与案例一相似,但是传递的是指针,能修改地址中存储的值,所以返回的是1

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Go 函数返回过程完整流程
  • 案例分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档