在godoc(https://blog.golang.org/defer-panic-and-recover)中,有一个例子:
- 延迟函数可以读取并分配给返回函数的命名返回值。
醇>在此示例中,延迟函数递增返回值i 在周围的函数返回后。因此,此函数返回2:
func c() (i int) {
defer func() { i++ }()
return i
}
我还写了一个小程序:
package main
import "fmt"
func b() int {
i := 0
for ; i < 4; i++ {
defer func() {fmt.Println(i); i++} ()
}
return i
}
func main() {
fmt.Println("result = ", b())
}
输出是:
4
5
6
7
result = 4
所以我很困惑,为什么第二个例子不输出8
?
答案 0 :(得分:9)
请注意“可以读取并分配给返回函数的命名返回值”的部分。
这意味着:
func b() int {
var i int
defer func() { fmt.Println(i); i++ }()
return i
}
会说0
和result = 0
,而:
func b() (i int) {
defer func() { fmt.Println(i); i++ }()
return i
}
会说0
和result = 1
。
可能有助于想象我的第一个示例中的return i
将i
值分配给隐藏的返回变量(因为它没有命名),然后继续执行defer
语句(仅修改局部变量i
),而在第二个示例中,我们直接分配给返回变量(因为它的名称),因此defer
语句能够更改它。
基本上你的程序可以解释如下:
package main
import "fmt"
func b() (hiddenVariable int) {
i := 0
for ; i < 4; i++ {
defer func() { fmt.Println(i); i++ }()
}
hiddenVariable = i; return // implicit meaning of return i
}
func main() {
fmt.Println("result = ", b())
}
答案 1 :(得分:0)
完全基于我所了解的延迟和查看代码之后,我想说for循环将打印延迟到后续版本,直到稍后, for循环仍在运行,因此会影响“我”。归来的 func b(),即4。
for ; i < 4; i++ {
defer func() {fmt.Println(i); i++} ()
}
return i
因为印刷声明及其价值&#39;因为我是&#39;推迟,他们增加超过4,但是&#39; i&#39;在for循环保持在4之后。
答案 2 :(得分:0)
import shutil
import datetime
import os
SOURCE = "C:/Program Files(x86) /FOLDER1/LOGS"
AppendDate=datetime.datetime.now()
BACKUP = "C:/Users/ME/Desktop/FOLDERNEW/LOGS %s" % AppendDate
shutil.copytree(SOURCE,BACKUP)
print os.listdir(BACKUP)
您的 func b()在语义上等同于:
A defer statement pushes a function call onto a list. The list of saved calls is executed after the surrounding function returns.
Ergo b()返回4.