关于golang中,defer的一个疑问

代码如下:

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入栈的时候做解析。
希望有两米八的老铁能解惑!!!

posted @ 2023-01-12 21:01  绿豆淀粉好勾芡儿  阅读(18)  评论(0)    收藏  举报