Golang,指向具有值接收者的函数的函数指针,在第二次调用时不会使用更改后的接收者调用该函数
Golang, function pointer to function with value receiver, does not call that function with the changed receiver, when called for the second time
package main
import (
"fmt"
)
type vector struct {
x int
y int
}
func (u vector) add(v vector) vector {
fmt.Println("received: ", u)
u.x += v.x
u.y += v.y
return u
}
func main() {
vecA := vector{x: 5, y: 10}
vecB := vector{x: 6, y: 7}
fp := vecA.add // 1
vecA = fp(vecB) // 2
fmt.Println(vecA)
vecA = fp(vecB) // 3
fmt.Println(vecA)
}
/*
Output:
received: {5 10}
{11 17}
received: {5 10}
{11 17}
*/
在标记 1 处,我用 add
函数声明并初始化了 fp
,使用 vecA
作为接收者。在标记 2 处,我更改了 vecA
的值。现在在 3,如果我们展开语句:fp(vecA)
,它变成:vecA.add(vecB)
。现在我认为它应该使用 'changed' vecA
调用 add
函数(在标记 2 时更改),而不是 [=14= 的旧值](在标记 1),但它调用 add
函数与 'old' vecA
(在标记 1),从输出中可以清楚地看出。 为什么?
尽管我找到了一种使用新 vecA
的方法,如下所示:
package main
import (
"fmt"
)
type vector struct {
x int
y int
}
func (u *vector) add(v vector) {
fmt.Println("received: ", *u)
u.x += v.x
u.y += v.y
}
func main() {
vecA := &vector{x: 5, y: 10}
vecB := vector{x: 6, y: 7}
fp := vecA.add // 1
fp(vecB) // 2
fmt.Println(*vecA)
fp(vecB) // 3
fmt.Println(*vecA)
}
/*
Output:
received: {5 10}
{11 17}
received: {11 17}
{17 24}
*/
Now I think it should call add function with the 'changed' vecA
不对,这种想法是错误的。 fp 是并保持绑定到旧值。
在您的第一个示例中,fp 使用 vecA 的值,因此在初始分配后 vecA 发生的任何事情都不会反映在 fp 中。
在您的第二个示例中,fp 使用 vecA 的地址。现在您将内存位置中 vecA 的值传递给 add func(),以便它使用更新后的值。
package main
import (
"fmt"
)
type vector struct {
x int
y int
}
func (u vector) add(v vector) vector {
fmt.Println("received: ", u)
u.x += v.x
u.y += v.y
return u
}
func main() {
vecA := vector{x: 5, y: 10}
vecB := vector{x: 6, y: 7}
fp := vecA.add // 1
vecA = fp(vecB) // 2
fmt.Println(vecA)
vecA = fp(vecB) // 3
fmt.Println(vecA)
}
/*
Output:
received: {5 10}
{11 17}
received: {5 10}
{11 17}
*/
在标记 1 处,我用 add
函数声明并初始化了 fp
,使用 vecA
作为接收者。在标记 2 处,我更改了 vecA
的值。现在在 3,如果我们展开语句:fp(vecA)
,它变成:vecA.add(vecB)
。现在我认为它应该使用 'changed' vecA
调用 add
函数(在标记 2 时更改),而不是 [=14= 的旧值](在标记 1),但它调用 add
函数与 'old' vecA
(在标记 1),从输出中可以清楚地看出。 为什么?
尽管我找到了一种使用新 vecA
的方法,如下所示:
package main
import (
"fmt"
)
type vector struct {
x int
y int
}
func (u *vector) add(v vector) {
fmt.Println("received: ", *u)
u.x += v.x
u.y += v.y
}
func main() {
vecA := &vector{x: 5, y: 10}
vecB := vector{x: 6, y: 7}
fp := vecA.add // 1
fp(vecB) // 2
fmt.Println(*vecA)
fp(vecB) // 3
fmt.Println(*vecA)
}
/*
Output:
received: {5 10}
{11 17}
received: {11 17}
{17 24}
*/
Now I think it should call add function with the 'changed' vecA
不对,这种想法是错误的。 fp 是并保持绑定到旧值。
在您的第一个示例中,fp 使用 vecA 的值,因此在初始分配后 vecA 发生的任何事情都不会反映在 fp 中。
在您的第二个示例中,fp 使用 vecA 的地址。现在您将内存位置中 vecA 的值传递给 add func(),以便它使用更新后的值。