请考虑以下代码:
type foo struct {
bar string
}
func f() *foo {
ret := &foo{"before"}
defer func() { ret.bar = "after" }()
return ret
}
func main() {
fmt.Println(f()) // prints "&{after}"
}
动机是必须返回一个结构但是只有一些字段需要在返回之前设置(例如,函数完成时的时间戳)。
推迟现场分配的竞争条件? 这是惯用的吗? 有没有更好的办法?
答案 0 :(得分:1)
使用defer
语句与从函数或例程返回之前调用某些内容的主要好处是defer
即使在返回之前发生恐慌时也会运行该语句。
因此,它通常用于清理资源(例如关闭文件或网络连接)而不是设置状态。
以下功能不会打印或返回"你好"
func f() string {
panic("omg")
fmt.Println("hello")
return "hello"
}
此代码将打印但不会返回" hello"
func f() string {
defer fmt.Println("ello")
panic("omg")
return "hello"
}
回答你的问题:不,它不会导致比赛。除了上述差异之外,它等同于在return
语句之前调用某些内容。
答案 1 :(得分:1)
您在功能完成时提及时间戳。在这种情况下,您可以像这样使用defer
:
package main
import (
"fmt"
"time"
)
func main() {
foo()
}
func foo() {
defer trace("foo")()
time.Sleep(1 * time.Second)
}
func trace(fn string) func() {
start := time.Now()
return func() {
layout := "15:04:05.000"
end := time.Now()
fmt.Printf("%s start at %s, end at %s, total %s", fn, start.Format(layout), end.Format(layout), end.Sub(start))
}
}
输出:foo start at 23:00:00.000, end at 23:00:01.000, total 1s