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,我使用fp
作为接收者,通过add
函数声明并初始化了vecA
。在标记2时,我更改了vecA
的值。现在在3,如果我们扩展语句:fp(vecA)
,则变为:vecA.add(vecB)
。现在,我认为它应使用“已更改” add
(在标记2处更改)而不是vecA
的旧值(在标记1处)调用vecA
函数,但它正在调用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}
*/
行为上的差异与函数指针无关。
区别在于,在一种情况下,目标是值func (u vector)
,在另一种情况下,目标是指向值func (u *vector)
的指针。
当目标u
是一个值时,我们将获得该值的副本。修改u
就是修改在函数执行结束时丢弃的副本。
当目标u
是指向该值的指针时,将修改原始值。
因此,如果函数add
需要修改目标值u
,则目标必须是指向该值的指针。