Golang中的defer用于在调用者/外部函数上执行操作吗?

huangapple go评论90阅读模式
英文:

Golang Defer to act on caller / outer function?

问题

能够将defer延迟到外部函数的末尾吗?

// 普通事务
func dbStuff(){
    db.Begin()
    ...
    db.Commit()
}

// 使用defer的普通事务
func dbStuff(){
    db.Begin()
    defer db.Commit()
    ...
}

**这种情况是否可行**

// 可以将defer延迟到调用者/外部函数吗?
func dbStuff(){
    db.Trans()
    ...
}

// 当dbStuff()返回时,将执行Commit()
func (db Db) Trans(){
    db.Begin()
    defer db.Commit() // 延迟到调用者/外部函数
}

以上是要翻译的内容。

英文:

Is it possible to defer to the end of an outer function?

// normal transaction
func dbStuff(){
    db.Begin()
    ...
    db.Commit()
}

// normal transaction w/ defer
func dbStuff(){
    db.Begin()
    defer db.Commit()
    ...
}

Is this possible?

// can you defer to caller / outer function?
func dbStuff(){
    db.Trans()
    ...
}

// will Commit() when dbStuff() returns
func (db Db) Trans(){
    db.Begin()
    defer db.Commit() // to caller/outer function
}

答案1

得分: 9

根据规范,这是不可能的

"defer"语句调用一个函数,该函数的执行被延迟到周围函数返回的时刻,无论是因为周围函数执行了return语句,到达了函数体的末尾,还是因为相应的goroutine正在发生panic。(强调是我的)

更新:除此之外,这也不是一个好主意——Go语言的一个优点就是“所见即所得”。将内部函数中的函数延迟到外部函数会在控制流中创建“不可见”的变化。

英文:

According to the specification, it's not possible:

> A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.

(emphasis mine)

Update: Apart from that, it would not be a good idea either – one of the strengths of Go is "what you see is what you get". Deferring functions from inner functions to outer functions would create 'invisible' changes in your control flow.

答案2

得分: 8

这可能会有所帮助。

func main() {
    defer greet()() 
    fmt.Println("这里有一些代码...")
}

func greet() func() {
    fmt.Println("你好!")
    return func() { fmt.Println("再见!") } // 这将被延迟执行
}

输出:

你好!
这里有一些代码...
再见!

参考:https://asanchez.dev/blog/defer-golang-on-entry/

英文:

This might be helpful.

func main() {
    defer greet()() 
    fmt.Println("Some code here...")
}

func greet() func() {
    fmt.Println("Hello!")
    return func() { fmt.Println("Bye!") } // this will be deferred
}

Output:

Hello!
Some code here...
Bye!

Reference: https://asanchez.dev/blog/defer-golang-on-entry/

huangapple
  • 本文由 发表于 2014年2月8日 01:32:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/21634192.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定