测试代码一:
func TestDefer(t *testing.T) { fmt.Println("a") defer fmt.Println("b") defer c() defer d() fmt.Println("f") } func c() { fmt.Println("c") } func d() func(){ fmt.Println("d") return func() { fmt.Println("e") } }
输出为 a f d c b
结论:defer函数在函数执行结束后执行,若有多个defer函数,则执行顺序为后进先出(从下向上)
测试代码二:
func TestDefer(t *testing.T) { fmt.Println("a") defer fmt.Println("b") defer c() defer d()() fmt.Println("f") } func c() { fmt.Println("c") } func d() func(){ fmt.Println("d") return func() { fmt.Println("e") } }
这段代码只是在调用d方法时加了个括号,那么d方法就会立即执行
返回结果为 a d f e c b
我们可以看到 被defer标记的d函数中的程序“立即执行”,而d函数返回的函数则在测试方法结束后 按照“后进先出”的顺序执行。我们可以利用这个特性(函数主体立即执行,返回的函数在主函数结束后执行)做一些功能,如显示函数的执行时间
package main import ( "fmt" "log" "time" ) func main() { bigSlowOperation() } func bigSlowOperation() { defer trace("bigSlowOperation func")() // do NOT forget the extra parentheses fmt.Println("big slow operation after defer trace") // ... lots of work time.Sleep(10 * time.Second) } func trace(msg string) func() { start := time.Now() log.Printf("enter %s", msg) return func() { log.Printf("exit %s (%s)", msg, time.Since(start)) } } // 输出结果: /* MacBook-Pro:defer_statement zhenxink$ go run defer_order.go 2020/07/23 00:55:27 enter bigSlowOperation func big slow operation after defer trace 2020/07/23 00:55:37 exit bigSlowOperation func (10.002503591s) MacBook-Pro:defer_statement zhenxink$ */
Deferred function run after return statements have updated the function's result variables. Because an anonynous function can access its enclosing function's variables, including named results, a deferred anonymous function can observe the function's results.
A defered anonynous function can even change the values that the enclosing function returns to its caller.
package main import "fmt" func main() { double(4) fmt.Println(triple(4)) } func double(x int) (result int) { defer func() { fmt.Printf("double(%d) = %d ", x, result) }() // 该匿名函数要加上 () return x + x } func triple(x int) (result int) { defer func() { result += x }() return double(x) } // 运行结果: /* MacBook-Pro:defer_anonymous_func zhenxink$ go run defer_anonym_func.go double(4) = 8 double(4) = 8 12 MacBook-Pro:defer_anonymous_func zhenxink$ */
fmt.Println 和 log.Println 的区别:
参考链接: https://www.sunzhongwei.com/golang-log-println-fmt-println-diff?from=sidebar_new