defer示例代码
go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("golang version:", runtime.Version())
defer_demo()
}
func defer_demo() {
defer println()
for counter, n := 0, 0; n < 3; n++ {
defer func(v int) {
fmt.Print(counter)
counter++
}(n)
}
}
代码说明
这个代码先打印了使用的golang的版本,然后进行一个for循环,for循环中定义了一个defer func,打印出循环时定义的变量counter的值,在counter自增 go run xxx.go
看下结果
golang 1.21的运行结果
go run demo/defer.go
golang version: go1.21.5
012
可以看到在1.21.5这个版本中,打印出来的counter值自增成功了,在1.22中又会如何呢
golang 1.22的运行结果
go run demo/defer.go
golang version: go1.22.1
000
可以看到在1.22.1的这个版本中,打印出来的值都是一样的。
再举个例子
go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("golang version:", runtime.Version())
defer_demo()
}
func defer_demo() {
for i := 0; i < 3; i++ {
defer func() {
fmt.Println(i)
}()
}
}
在1.21的版本中的结果:
go run demo/defer2.go
golang version: go1.21.5
3
3
3
可以看到ids这个slice中的值都是10
在1.22的版本中的结果
go run demo/defer2.go
golang version: go1.22.1
2
1
0
修改方法
第一个例子本意应该是让counter自增的,可以把counter的定义放在循环外面.修改后的代码
go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("golang version:", runtime.Version())
defer_demo()
}
func defer_demo() {
counter := 0
defer println()
for n := 0; n < 3; n++ {
defer func(v int) {
fmt.Print(counter)
counter++
}(n)
}
}
1.21和1.22的执行结果
go run demo/defer.go
golang version: go1.21.5
012
go run demo/defer.go
golang version: go1.22.1
012
针对第二个例子改动比较简单,把循环变量作为defer func的参数即可,修改后的代码
go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("golang version:", runtime.Version())
defer_demo()
}
func defer_demo() {
for i := 0; i < 3; i++ {
defer func(i int) {
fmt.Println(i)
}(i)
}
}
这样1.21和1.22的结果就都一样了
go run demo/defer2.go
golang version: go1.21.5
2
1
0
go run demo/defer2.go
golang version: go1.22.1
2
1
0
第二个例子如果把defer func换成一个closures也会出现1.21和1.22打印不一样的情况
代码
go
package main
import (
"fmt"
"runtime"
)
func main() {
fmt.Println("golang version:", runtime.Version())
defer_demo()
}
func defer_demo() {
var demoFunc func()
for i := 0; i < 3; i++ {
if demoFunc == nil {
demoFunc = func() {
fmt.Println(i)
}
}
demoFunc()
}
}
运行结果
go run demo/closures.go
golang version: go1.21.5
0
1
2
go run demo/closures.go
golang version: go1.22.1
0
0
0