Go 延迟对命名返回值的行为

Go 延迟对命名返回值的行为,go,Go,在本例中,延迟函数在周围函数返回后增加返回值I。因此,此函数返回2: func c() (i int) { defer func() { i++ }() return 1 } 这怎么会返回2 延迟函数可以读取并分配返回函数的命名返回值 我想程序员的意图是返回1作为结果,并想知道为什么它会被覆盖,以及背后是什么设计决策。延迟函数是在该返回语句设置任何结果参数之后,但在函数返回其调用方之前执行的。 执行顺序: func c() (i int) { // i = 0 def

在本例中,延迟函数在周围函数返回后增加返回值I。因此,此函数返回2:

func c() (i int) {
    defer func() { i++ }()
    return 1
}
这怎么会返回2

延迟函数可以读取并分配返回函数的命名返回值


我想程序员的意图是返回1作为结果,并想知道为什么它会被覆盖,以及背后是什么设计决策。

延迟函数是在该返回语句设置任何结果参数之后,但在函数返回其调用方之前执行的。
执行顺序:

func c() (i int) { // i = 0
    defer func() { i++ }()
    return 1  // i = 1
 // run deferred function here i++ => i = 2
}
请参阅一个for
defer
关键字

见:

每次执行一个“defer”语句时,调用的函数值和参数都会被重新保存,但实际函数不会被调用。相反,延迟函数是在周围函数返回之前立即调用的,其顺序与延迟函数的顺序相反。也就是说,如果周围的函数通过显式return语句返回,则在该return语句设置任何结果参数之后,但在函数返回其调用方之前,执行延迟函数。如果延迟函数值的计算结果为nil,则在调用函数时执行恐慌,而不是在执行“defer”语句时执行恐慌。
例如,如果延迟函数是一个函数文本,并且周围的函数已经命名了文本范围内的结果参数,那么延迟函数可以在返回结果参数之前访问和修改这些参数。如果延迟函数有任何返回值,则在函数完成时将丢弃这些值。(另请参见“处理恐慌”一节。)

锁(l)
延迟解锁(l)//在周围函数返回之前发生解锁
//在周围函数返回之前打印3 2 1 0

对于i:=0;i延迟函数是在返回语句设置任何结果参数之后,但在函数返回到调用方之前执行的。
执行顺序:

func c() (i int) { // i = 0
    defer func() { i++ }()
    return 1  // i = 1
 // run deferred function here i++ => i = 2
}
请参阅一个for
defer
关键字

见:

每次执行一个“defer”语句时,调用的函数值和参数都会被重新保存,但实际函数不会被调用。相反,延迟函数是在周围函数返回之前立即调用的,其顺序与延迟函数的顺序相反。也就是说,如果周围的函数通过显式return语句返回,则在该return语句设置任何结果参数之后,但在函数返回其调用方之前,执行延迟函数。如果延迟函数值的计算结果为nil,则在调用函数时执行恐慌,而不是在执行“defer”语句时执行恐慌。
例如,如果延迟函数是一个函数文本,并且周围的函数已经命名了文本范围内的结果参数,那么延迟函数可以在返回结果参数之前访问和修改这些参数。如果延迟函数有任何返回值,则在函数完成时将丢弃这些值。(另请参见“处理恐慌”一节。)

锁(l)
延迟解锁(l)//在周围函数返回之前发生解锁
//在周围函数返回之前打印3 2 1 0

对于i:=0;i延迟匿名函数可以访问和修改周围函数的命名返回参数

根据规范:

例如,如果延迟函数是一个函数文本,并且周围的函数命名了文本范围内的结果参数,则延迟函数可以在返回结果参数之前访问和修改这些参数。如果延迟函数有任何返回值,当函数完成时,它们将被丢弃


延迟匿名函数可以访问和修改周围函数的命名返回参数

根据规范:

例如,如果延迟函数是一个函数文本,并且周围的函数命名了文本范围内的结果参数,则延迟函数可以在返回结果参数之前访问和修改这些参数。如果延迟函数有任何返回值,当函数完成时,它们将被丢弃


程序员的意图是返回return语句中指定的值加1。返回整数是一个很好的例子,可以理解发生了什么,但错误返回的值通常会被修改。程序员的意图是返回return语句中指定的值加1。返回整数是一个很好的例子了解发生了什么,但错误返回值通常会被修改。