我刚开始学习Go,但是我对一个例子感到困惑,那就是在The Go Blog中使用defer更改命名的返回值-Defer,Panic和Recover。
该示例说:
延迟函数可以读取并分配给返回函数的命名返回值。 在此示例中,延迟函数在周围函数返回后递增返回值i。因此,此函数 返回2 :
在此示例中,延迟函数在周围函数返回后递增返回值i。因此,此函数 返回2 :
func c() (i int) { defer func() { i++ }() return 1 }
但正如我从A Go of Go中学到 的-命名返回值
不带参数的return语句 返回命名的返回值。这就是所谓的“裸”回报。
我在下面的代码中进行了测试,并在函数中b返回1,因为它不是上面提到的“ 无参数的返回语句 ”情况。
b
func a() (i int) { // return 2 i = 2 return } func b() (i int) { // return 1 i = 2 return 1 }
所以我的问题是在第一个示例中,周围的函数c有一个命名的返回值i,但是该函数c使用return 1第二个示例中的函数,无论值i是多少,我们都可以看到它应该具有return 1 。但是,为什么在i更改延迟函数后,该c函数返回值i而不是值1?
c
return 1
i
在输入问题时,我可能已经猜到了答案。是因为:
等于:
i = 1 return
在具有命名返回值变量的函数中i?
请帮我确认一下,谢谢!
defer语句将函数调用推送到列表上。周围函数返回后,将执行保存的呼叫列表。- 转到博客:延期,恐慌和恢复
理解上述陈述的另一种方式:
defer语句 将 函数调用压入 堆栈 。 弹出 的已保存调用 (LIFO) 和延迟函数的堆栈在周围函数返回之前立即被调用。
返回1后,func() { i++ }()将执行延迟。因此,按执行顺序:
func() { i++ }()
为了理解起见:
func c() (i int) { defer func() { fmt.Println("third") }() defer func() { fmt.Println("second") }() defer func() { fmt.Println("first") }() return 1 }
执行顺序: