我刚开始学习Go,我被一个关于使用延迟更改Go博客-推迟,恐慌,和恢复中的命名返回值的例子搞混了。
这个例子说:
在本例中,延迟函数在周围函数返回后增加返回值i。因此,此函数返回2
func c() (i int) {
defer func() { i++ }()
return 1
}
但正如我从返回值的回访中学到的
不带参数的语句返回命名的返回值。这就是所谓的“赤裸”的回归。
我在下面的代码中进行了测试,在函数b
中,它返回1,因为它不是上面提到的“无参数返回语句”的情况。
func a() (i int) { // return 2
i = 2
return
}
func b() (i int) { // return 1
i = 2
return 1
}
所以我的问题是在第一个例子中,周围的函数c有一个命名的返回值i,但是函数c
使用return 1
,在第二个例子中,我们可以看到它应该有返回1,而不管i
是什么值。但是,为什么在i
更改了延迟函数之后,c
函数返回i
的值而不是值1?
当我键入问题时,我可能已经猜到了答案。是因为:
return 1
等于:
i = 1
return
在具有命名返回值变量i
的函数中。
请帮我确认一下,谢谢!
发布于 2016-05-16 07:47:26
延迟语句将函数调用推入到列表中。保存的调用列表是在周围函数返回后执行的。-- Go博客:推迟,恐慌,恢复
理解上述陈述的另一种方式:
延迟语句将函数调用推送到堆栈上。保存的调用堆栈弹出(LIFO)和延迟函数将在周围函数返回之前立即调用。
func c() (i int) {
defer func() { i++ }()
return 1
}
返回1之后,将执行延迟func() { i++ }()
。因此,按处决顺序:
为了理解:
func c() (i int) {
defer func() { fmt.Println("third") }()
defer func() { fmt.Println("second") }()
defer func() { fmt.Println("first") }()
return 1
}
处决令:
发布于 2016-05-16 10:47:34
发布于 2017-03-16 10:49:24
我认为混淆是关于函数的,如果你这样分类的话:
func main() {
fmt.Println(c()) //the result is 5
}
// the c function returned value is named j
func c() (j int) {
defer changei(&j)
return 6
}
func changei(j *int) {
//now j is 6 because it was assigned by return statement
// and if i change guess what?! i changed the returned value
*j--;
}
但是,如果返回值不是这样命名的:
func main() {
fmt.Println(c()) //the result will become 6
}
// the c function returned value is not named at this time
func c() int {
j := 1
defer changei(&j)
return 6
}
func changei(j *int) {
//now j = 1
// and if i change guess what?! it will not effects the returned value
*j--;
}
我希望这能消除混乱,这就是我如何快乐地编码。
https://stackoverflow.com/questions/37248898
复制相似问题