Go 语言中defer语句运用时需要注意的地方

先来看下面的代码

执行结果是1

再来看下面这段

执行结果是 14

为什么显示声明返回值和不显示申明就会有不一样的返回结果呢?关于这个问题首先要明确下Go语言中defer的执行顺序是后进先出的。

为了支持多返回值,GO的返回是通过栈的方式,C语言用的是寄存器。在return执行前,会把要return的值或者引用的变量设置成返回值(可以理解为设置返回值= 要返回的值或变量,这一步是压栈操作.函数要return的是返回值,返回值,返回值!!!这个返回值可以在函数声明中显示定义,如果没有定义那就会把return 的变量X赋给返回值这个东东),这个时候如果有defer语句的话,会在return之前执行defer语句,最后将栈中的值或者变量返回(也就是return 返回值)。因此如果在入栈后还对栈中的基本类型进行操作,不会改变返回值的结果,如果对指针类型进行操作,会改变返回值的结果。

sum2(n …int)int 函数的返回值是基本类型,并且没有被提前声名,其值来自于其他变量的赋值,而defer中修改的也是其他变量,而非返回值本身,因此函数退出时返回值并没有被改变。也就是说,sum2的return执行步骤如下:

sum2(n …int)int函数的返回值被提前声名(相当于告诉你sum就是返回值,返回值就是sum),也就意味着defer中是可以调用到真实返回值的,因此defer在return赋值返回值 i 之后,再一次地修改了 i 的值,最终函数退出后的返回值才会是defer修改过的值。而sum1的return执行步骤如下

刚刚说了,如果是引用变量的话就可以不显示声明返回值名称,也可以做到在defer中修改返回值的效果,代码如下:

输出如下

个人觉得 defer还是不要随意的使用,主要还是用于释放资源等操作。

——Snake

 

 

 

 

 

 

 

 

snake

作者: snake

我们需要为这个社会做一点贡献,失去了才懂得去珍惜。

发表评论

电子邮件地址不会被公开。 必填项已用*标注