defermain
package main

import (
	"fmt"
	"time"
)

func main() {
	startedAt := time.Now()
	defer fmt.Println(time.Since(startedAt))
	time.Sleep(time.Second) //休眠一秒
} 
复制代码

结果是:

D:\workspace\go\src\test>go run main.go
0s 
复制代码
defertime.Since(startedAt)maindefer

我们再来看个简单例子来说明上述解释:

package main

import (
	"fmt"
)

func main() {
	i := 1
	defer fmt.Println(test(i))
	i = 100
}

func test(i int) int {
	i = i + 1
	return i
} 

D:\workspace\go\src\test>go run main.go
2 
复制代码
会把defer右边最外层函数的参数计算完毕,并传递进函数里但不会执行函数体的代码直到包裹defer的函数返回

我们再来看一个例子与匿名函数结合:

package main

import (
	"fmt"
)

func main() {
	i := 1
	defer func() {
		fmt.Println(test(i))
	}()
	i = 100
}

func test(i int) int {
	i = i + 1
	return i
} 
复制代码

结果:

D:\workspace\go\src\test>go run main.go
101  
复制代码
但不会执行函数体的代码直到包裹defer的函数返回
{ fmt.Println(test(i)) }()

所以你要解决第一个打印为0s的问题,你就可以使用匿名函数来解决,如下:

package main

import (
	"fmt"
	"time"
)

func main() {
	startedAt := time.Now()
	defer func() {
		fmt.Println(time.Since(startedAt))
	}()
	time.Sleep(time.Second) //休眠一秒
} 
复制代码

结果:

D:\workspace\go\src\test>go run main.go
1.0152825s 
复制代码