当函数作为函数的参数给出时,它是按值传递还是按指针传递 [closed]

When a function is given as an argument to a function, is it pass-by-value or pass-by-pointer [closed]

提问人:snath03 提问时间:8/6/2022 更新时间:8/6/2022 访问量:123

问:


这个问题是由一个错别字或一个无法再重现的问题引起的。虽然类似的问题可能在这里成为主题,但这个问题的解决方式不太可能帮助未来的读者。

去年关闭。

举个例子——

func funcB() { fmt.Println("Hi") })
funcA(funcB)

是否接收指向 ?或者它是否正在接收一个成熟的不可变函数?funcAfuncB

所以,如果我执行这段代码——

func funcA() { fmt.Println("Hi") })
funcB(funcA)
funcC(funcA)
funcD(funcA)
funcE(funcA)
funcF(funcA)

是所有函数调用都在创建一个新对象,还是所有函数调用都接收指向 的相同指针?funcAfuncA

Go 指针 按值传递

评论

1赞 AminMal 8/6/2022
简单实验:func mutateFunction(f func(int)int) { f = nil }; f := func (i int) int { return i * 2}; mutateFunction(f); fmt.Println(f(2));
2赞 JimB 8/6/2022
按值传递函数意味着什么?Go 是一种编译语言,因此函数必须对可执行代码进行某种引用。
3赞 Volker 8/6/2022
这个问题没有意义,编写 Go 代码不需要答案。
1赞 torek 8/6/2022
你如何区分?

答:

3赞 JFMR 8/6/2022 #1

函数不包含要通过值或引用传递的状态,即它们只是可执行代码。当您将一个函数传递给另一个函数时,您正在引用函数主体的可执行代码。

匿名函数怎么样?

还可以将匿名函数或闭包存储到值中。在这种情况下,您的问题变得更加有趣,因为闭包可以保持状态。func()

闭包是通过值还是通过引用传递给函数?

func call(f func()) {
    f()
}

func main() {
    var i int

    f := func() {
        fmt.Println(i)
        i++
    }

    call(f)
    call(f)
}

运行上述代码输出:

0
1

我们可以得出结论,闭包的状态(即捕获的变量)在调用 之间以某种方式共享。原则上,这种行为可以通过以下方式实现:icall()

  1. 闭包通过引用捕获其环境,并按值或引用传递。
  2. 闭包按值捕获其环境,并且仅通过引用传递。

为了了解闭包如何捕获其环境,我们可以更改 in 的值,并查看闭包看到的值是否受到影响。如果我们将下面的代码附加到:imain()imain()

i = 100
call(f)

然后,显示。因此,在 和 之间共享 和 闭包(即,闭包没有自己的 副本)。因此,闭包通过引用来捕获其环境(我们现在可以排除上面的 2. 选项)。100imain()i

在这一点上,我们仍然没有发现闭包是按值传递还是按引用传递。但是,我们已经知道,闭包的捕获状态实际上是通过引用函数传递的,因为闭包包含对捕获状态的引用。这很可能是最关键的见解。

即便如此,我们还是可以看到闭包是按值传递的:

func change(f func()) {
    f = func() {
        fmt.Println("replaced")
    }
}

func main() {
    f := func() {
        fmt.Println("original")
    }

    change(f)
    f() // prints "original"
}

结论

  • 函数只是代码。它们不存储状态。函数是某些可执行代码的内存地址。当您将一个函数传递给另一个函数时,您正在提供此地址。

  • 匿名函数或闭包可以保存与封闭环境相对应的状态。即使闭包是按值传递的,它们所持有的状态也是对它们捕获的环境的引用。因此,最终效果是闭包捕获的环境通过引用传递。

评论

0赞 newacct 8/7/2022
“即便如此,我们还是可以看到闭包是按值传递的:”Go 中的每个类型都是“按值传递”的,从某种意义上说,在被调用函数中对参数变量的赋值对调用范围没有任何影响。也许您的意思是函数是值类型还是引用类型?但是,在这个问题上,你所展示的任何东西都没有以一种或另一种方式证明它,也许没有语义可以让我们测试这一点。