当在链式方法调用中使用`defer`时会发生什么?

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

What will happen when using `defer` in chained method call?

问题

例如,

defer profile.Start().Stop()

等同于:

p := profile.Start()
defer p.Stop()
英文:

for example,

defer profile.Start().Stop()

is that equal to:

p := profile.Start()
defer p.Stop()

答案1

得分: 11

你可以使用defer关键字来延迟执行一长串的方法调用,但只有最后一个函数调用会被延迟执行,而其他所有的调用都会立即被评估。在上面的示例中,只有对函数H()的调用被延迟执行,为了达到H(),所有其他的函数调用都必须立即被评估。

更多信息请参考Effective Go

英文:

You can defer a long chain of method calls but only the last function call will be deferred and all other calls will be evaluated immediately with the defer statement.

func foo() {
   defer A().B().C().D().E().F().G().H()
   // Only call to H() is deferred and all other function calls must be 
   // evaluated immediately to reach H.
}

For more info see Effective Go.

答案2

得分: 2

在级联函数中,defer关键字只对最后一个函数调用起作用。其他函数将按照评估顺序立即调用。

例如:

func secondInteration(p *profile){
    fmt.Println("~~~~~~~~~~ Second Iteration ~~~~~~~~")
    defer p.start().stop()
    p.intermediate()
}

这只会延迟stop函数的执行。start和intermediate函数将按照正常执行的顺序调用。

上面的代码片段将输出:

~~~~~~~~~~ Second Iteration ~~~~~~~~
start
Intermediate
stop

而如果有多个deferred函数,这些函数将被推入堆栈,最后推入的defer函数将首先执行。

例如:

func thirdInteration(p *profile){
    fmt.Println("~~~~~~~~~~ Third Iteration ~~~~~~~~")
    defer p.start()
    defer p.intermediate()
    defer p.stop()
}

这将输出:

~~~~~~~~~~ Third Iteration ~~~~~~~~
stop
Intermediate
start

因此,在这个上下文中,上述代码片段在效果上是相同的,因为只有一个方法被链接,并且只有一行代码。

我们可以在这里找到更多关于Go博客的信息。

上述代码片段可以在这里找到。

英文:

The defer in the cascaded function defer only to the last function call. The other functions will be called immediately as per the order of evaluation.

For example

func secondInteration(p *profile){
	fmt.Println("~~~~~~~~~~ Second Iteration ~~~~~~~~")
	defer p.start().stop()
	p.intermediate()
	
}

This will only defer the stop function. Start and intermediate will be evaluated as a normal execution.

The above snippet will print

~~~~~~~~~~ Second Iteration ~~~~~~~~
start
Intermediate
stop

Whereas if you have more than one deferred function, the functions will be pushed into the Stack and the last pushed defer function will be evaluated first

For example

func thirdInteration(p *profile){
	fmt.Println("~~~~~~~~~~ Third Iteration ~~~~~~~~")
	defer p.start()
	defer p.intermediate()
	defer p.stop()
}

This outputs into

~~~~~~~~~~ Third Iteration ~~~~~~~~
stop
Intermediate
start

So effectively the above code snippets are the same in this context as only one method is chained and we have one line of code.

We can find more information here on Go Blog.

The above code snippets can be found here

huangapple
  • 本文由 发表于 2021年7月19日 16:13:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/68437177.html
匿名

发表评论

匿名网友

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

确定