我刚开始学习golang,我得到了一个例子混淆有关使用推迟在golang博客文章更改名为返回值这里.
这个例子说:
- 延迟函数可以读取并分配给返回函数的命名返回值.
在此示例中,延迟函数在周围函数返回后递增返回值i.因此,此函数返回2:
func c() (i int) {
defer func() { i++ }()
return 1
}
Run Code Online (Sandbox Code Playgroud)
但正如我从A Tour of Go中学到 的 - 命名的回报值
不带参数的return语句返回指定的返回值.这被称为"裸体"回归.
我在下面的代码和函数b中测试它返回1,因为它不是上面提到的没有参数的A return语句.
func a() (i int) { // return 2
i = 2
return
}
func b() (i int) { // return 1
i = 2
return 1
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是在第一个例子中,周围的函数c有一个命名的返回值i,但函数c使用return 1,在第二个例子中我们可以看到它应该返回1,无论我是什么值.但是为什么在我更改延迟函数后,c函数返回i的值而不是值1?
当我输入我的问题时,我可能已经猜到了答案.是因为
return 1
Run Code Online (Sandbox Code Playgroud)
等于
i = 1
return
Run Code Online (Sandbox Code Playgroud)
在具有命名返回值变量i的函数中?
请帮我确认一下,谢谢!
Roy*_*Lee 36
defer语句将函数调用推送到列表中.在周围函数返回后执行已保存调用的列表.- Go Blog:推迟,恐慌和恢复
另一种理解上述陈述的方法:
延迟语句将函数调用推送到堆栈.弹出保存的调用堆栈(LIFO)和延迟函数在周围函数返回之前立即被调用.
func c() (i int) {
defer func() { i++ }()
return 1
}
Run Code Online (Sandbox Code Playgroud)
返回1后,func() { i++ }()执行延迟.因此,按执行顺序:
为了理解:
func c() (i int) {
defer func() { fmt.Println("third") }()
defer func() { fmt.Println("second") }()
defer func() { fmt.Println("first") }()
return 1
}
Run Code Online (Sandbox Code Playgroud)
处决顺序:
我认为混淆是关于功能的功能如果你这样分类怎么样:
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--;
}
Run Code Online (Sandbox Code Playgroud)
但如果返回值的名称不是这样的:
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--;
}
Run Code Online (Sandbox Code Playgroud)
我希望这将清除混乱,这就是我如何快乐Go编码
| 归档时间: |
|
| 查看次数: |
16319 次 |
| 最近记录: |