首页 > 其他分享 >go defer修改返回值

go defer修改返回值

时间:2023-12-07 16:35:13浏览次数:25  
标签:defer test3 test2 func go 返回值

golang在defer修改返回值时需要格外注意!

如果未提前声明返回值的话,在defer中修改返回值是无效的操作。原因如下:

package main

func test1() int {
	i := 1
	defer func() {   // 实际则是将局部变量i的地址指针传入,调用runtime.deferproc函数
		i++
	}()
	return i     // 将i的值拷贝到调用栈的返回值上
}

func test2() int {
	i := 1
	defer func(i int) {  // 将i的值拷贝一份传入,调用runtime.deferproc函数
		i++
	}(i)
	return i
}

func test3() (i int) { // 提前声明了返回值i
	i = 1
	defer func() { // 将返回值i的地址指针传入,调用runtime.deferproc函数
		i++
	}()
	return i  // 直接将值赋给调用栈的返回值上
}


func main() {
	fmt.Println(test1())
	fmt.Println(test2())
	fmt.Println(test3())
}

 

这三个方法的返回值

lichenyi@lichenyideMacBook-Pro test % go run test2.go
1
1
2

在test3中函数的返回值提前声明,这使得defer可以直接访问该返回值(因为传入了返回值i的地址指针)

在test1和test2中 defer无法直接访问到返回值(因为这两种情况传入的分别是局部变量i的指针和拷贝值,defer虽然正确运行了,但是test2和test3的函数栈在函数返回后就销毁了,所以局部变量i也销毁了,因此对于调用函数而言是无感知的,所以没有成功修改返回值)
————————————————
版权声明:本文为CSDN博主「李晨毅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_40486544/article/details/108741704

标签:defer,test3,test2,func,go,返回值
From: https://www.cnblogs.com/zhanchenjin/p/17883311.html

相关文章

  • [3分钟]GO:不要错误的使用并发
    七、并发由于Go语言的并发功能,经常被选作项目编程语言。Go语言团队已经竭尽全力以廉价(在硬件资源方面)和高性能来实现并发,但是Go语言的并发功能也可以被用来编写性能不高同时也不太可靠的代码。这里有一个二分法;Go语言的最大特点是简单、轻量级的并发模型。作为一种产品......
  • [效率大杀器] go工具篇:dlv + goland 实现远程调试
    dlv+Goland远程调试远程调试就是使用使用本地IDE来调试远程服务器上的服务。本地打断点,调用远程服务的接口。本地就会停在断点。相当于debug远程服务。优点是可以保持环境的一致性。dlv的安装git仓库:https://github.com/derekparker/delve将div安装到远程服务器。......
  • [小白入门指南] 如何使用gorm操作MySQL
    1.使用gorm的前置条件1.1MySQL的安装和配置1.2NaviacteForMySQL162.gorm基本操作2.1增2.2查2.3改2.4删2.5gorm迁移1.使用gorm的前置条件1.1MySQL的安装和配置Debian中安装MySQL|MySQL创建用户并授予权限#用rpm查看是否安装了MySQLrpm-qa|gr......
  • go-zero 开发入门-加法客服端示例
    定义RPC接口文件接口文件add.proto的内容如下:syntax="proto3";packageadd;optiongo_package="./add";messageAddReq{int32a=1;int32b=2;}messageAddResp{int32sum=1;}serviceAdder{rpcadd(AddReq)returns(A......
  • vscode-go语言插件,调试器协议分析(二)
    版本信息Server:{"Commands":["gopls.add_dependency","gopls.add_import","gopls.add_telemetry_counters","gopls.apply_fix","gopls.change_signature","gopls.check_u......
  • Django高级特性:django-apscheduler定时任务
     前言:在使用Django框架开发web项目时,很多时候需要设置定时任务或让用户手动在页面上设置定时任务在Django中实现定时任务功能大概有以下三种方法:Celery分布式任务队列。侧重实时操作,可用于生产系统处理数以百万计的任务,都用于大型项目,配置和使用较为复杂。由于它本身......
  • vscode-go语言插件,调试器协议分析
    c客户端,vscodes服务端,调试器----------------------------------------------c-->客户端,请求调试器初始化{"command":"initialize","arguments":{"clientID":"vscode","clientName":......
  • Django ORM 多表操作:一对一、一对多、多对多的增删改查 (二)
    DjangomodelORM数据表相关操作分析思路,创建数据表对于表操作,表之间的关联关系,必须理解他们之间的关系,对于编程很重要。可以看看映射关系、外键和relationship查询,至少明白外键相关基本知识。下面是简单的demo1.创建数据模型models.py文件,fromdjango.dbimportmodels#Cre......
  • Go--字符串函数
    示例:packagemainimport("fmt""strings")funcmain(){//strings.Contains():判断一个字符串是否包含另一个子字符串str:="Hello,World!"substr:="World"ifstrings.Contains(str,substr){//原始字符串、要查找的......
  • Golang标准库:syslog包代码示例
    以下是一个示例代码,展示了如何使用syslog包进行系统日志记录:packagemainimport( "log" "log/syslog")funcmain(){ //创建一个连接到本地系统日志的写入器 writer,err:=syslog.New(syslog.LOG_INFO,"Example") iferr!=nil{ log.Fatal("Failedtoconnect......