golang中延迟和命名的返回值是如何工作的? [英] How does defer and named return value work in golang?

查看:212
本文介绍了golang中延迟和命名的返回值是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习golang,并且对使用延迟更改golang博客文章中的命名返回值的一个示例感到困惑 这里



举例说:



  1. 延迟函数可以读取并分配给返回函数的返回值。

在这个例子中,延迟函数在周围函数返回后递增返回值i。因此,这个函数返回2



  func c() (i int){
defer func(){i ++}()
return 1
}

但正如我所了解的那样, Go Tour of Go-named返回值


不带参数的返回语句返回指定的返回值。这被称为裸返回。

我在下面的代码中进行了测试,并在函数b中返回1,因为它不是'

  func a()(i int) {//返回2 
i = 2
返回
}

func b()(int){//返回1
i = 2
return 1
}

所以我的问题是在第一个例子中, c有一个命名的返回值i,但函数c使用 return 1 ,在第二个例子中我们可以看到它应该返回1,无论我的值是多少。但是为什么在改变延迟函数之后,c函数返回值i而不是值1?

当我输入我的问题时,我可能猜到了答案。是因为

  return 1 

等于

  i = 1 $在具有命名返回值变量i的函数中,b $ b返回



请帮助我确认,谢谢!

解决方案


延迟语句将函数调用推入列表。保存的调用列表在周围函数返回后执行。 - 围棋博客:推迟,恐慌和恢复


blockquote>

理解上述语句的另一种方法:


延迟陈述推送将一个函数调用到堆栈上。保存的调用堆栈弹出(LIFO),并在函数返回后执行




  func c()(i int){
defer func(){i ++}()
return 1
}

返回1后,延迟 func(){i ++}()被执行。因此,按执行顺序:


  1. i = 1(return 1)
  2. i ++(推迟func从堆栈弹出并执行)

  3. i == 2(命名变量i的最终结果)






为了理解:

  func c()(i int ){
延迟FUNC(){fmt.Println( 第三)}()
延迟FUNC(){fmt.Println( 第二)}()
延迟FUNC() {fmt.Println(first)}()

return 1
}

执行顺序:


  1. i = 1(返回1)

  2. first

  3. second

  4. third


I just started learning golang and i got confused with one example about using defer to change named return value in the golang blog post here

The example says

  1. Deferred functions may read and assign to the returning function's named return values.

In this example, a deferred function increments the return value i after the surrounding function returns. Thus, this function returns 2:

func c() (i int) {
    defer func() { i++ }()
    return 1
}

But as what i have learned frmm A Tour of Go - Named return values

A return statement without arguments returns the named return values. This is known as a "naked" return.

I tested in the following code and in function b it returns 1 because it wasn't the A return statement without arguments case mentioned above.

func a() (i int) { // return 2
    i = 2
    return
}

func b() (i int) {  // return 1 
    i = 2
    return 1
}

So my question is in the first example, the surrounding function c has a named return value i, but the function c uses return 1 which in the second example we can see it should have return 1 no matter what value i is. But why after i changes in the deferred function the c function returns the value of i instead the value 1?

As i was typing my question, I might have guessed the answer. Is it because

return 1 

is equals to

i = 1
return 

in a function with a named return value variable i ?

Please help me confirm, thanks!

解决方案

A defer statement pushes a function call onto a list. The list of saved calls is executed after the surrounding function returns. -- The Go Blog: Defer, Panic, and Recover

Another way to understand the above statement:

A defer statements pushes a function call onto a stack. The stack of saved calls popped out (LIFO) and executed after the function returns.

 func c() (i int) {
    defer func() { i++ }()
    return 1
}

After 1 is returned, the defer func() { i++ }() gets executed. Hence, in order of executions:

  1. i = 1 (return 1)
  2. i++ (defer func pop out from stack and executed)
  3. i == 2 (final result of named variable i)


For understanding sake:

 func c() (i int) {
    defer func() { fmt.Println("third") }()
    defer func() { fmt.Println("second") }()
    defer func() { fmt.Println("first") }()

    return 1
}

Order of executions:

  1. i = 1 (return 1)
  2. "first"
  3. "second"
  4. "third"

这篇关于golang中延迟和命名的返回值是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆