代码如下:
package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
defer testA()
defer testB()()
defer testC()()()
fmt.Println("running")
chExit := make(chan os.Signal, 1)
signal.Notify(chExit, syscall.SIGINT, syscall.SIGTERM, syscall.SIGKILL, syscall.SIGHUP)
select {
case <-chExit:
fmt.Println("capture ctrl+c command, bye bye!")
}
}
func testA() {
fmt.Println("test a defer print 1")
}
func testB() func() {
fmt.Println("test b defer print 2")
return func() {
fmt.Println("test b defer print 3")
}
}
func testC() func() func() {
fmt.Println("test c defer print 4")
return func() func() {
fmt.Println("test c defer print 5")
return func() {
fmt.Println("test c defer print 6")
}
}
}
golang1.19环境下的输出为:
$ go run main.go
running
test b defer print 2
test c defer print 4
test c defer print 5
capture ctrl+c command, bye bye!
test c defer print 6
test b defer print 3
test a defer print 1
testA函数
testA函数的返回值在我的预期内。即在main函数结束时,执行defer。
testB函数
testB函数的返回值超出了我的预期。
我预期的结果是:
$ go run main.go
running
capture ctrl+c command, bye bye!
test b defer print 2
test b defer print 3
实际测试的结果却是:
$ go run main.go
running
test b defer print 2
capture ctrl+c command, bye bye!
test b defer print 3
我在网上查找了资料,没有明确的说法。
我自己强行解释为:testB的返回值为func,返回后被作为真正的defer执行了。而输出test b defer print 2
则是golang会在将defer入栈的时候做解析。
希望有两米八的老铁能解惑!!!