golang中关于return、defer和匿名函数的执行顺序

问题遇到的现象和发生背景

以下两端代码为什么一个输出5,一个输出6

问题相关代码,请勿粘贴截图
package main
   
import "fmt"
   
func f4() (x int) {
 defer func(x int) {
  x++
 }(x)
 return 5
}
   
func main() {
   fmt.Println(f4())//结果输出5
}


package main

import "fmt"

func f2() (x int) {
 defer func() {
  x++
 }()
 return 5
}

func main() {
 fmt.Println(f2())//结果输出6
}
运行结果及报错内容

debug显示第一份结果为5的代码中return 5 被执行了两次,是为什么啊

并不是return 执行了两遍,具名返回值可能会造成一些困扰,上面的程序等价于:

package main
   
import "fmt"
   
func f4() int {
    var x int

    defer func(x int) {
        x++
    }(x)

    x = 5
    return x

}
   
func main() {
   fmt.Println(f4())//结果输出5
}
 

不同之处在于 defer 接受了一个有参函数,因为 Go 是值拷贝,所以 defer 里执行加加的 x 和 返回值 x 不是同一个了,下面返回 6 的同理,defer 中执行加加的是父作用域的 x 也就是返回值 x