猿问

Golang,带有值接收器的函数的函数指针,在第二次调用时不会使用更改的接收器调用该函数

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}

*/

在标记1fp处,我使用add函数声明并初始化,vecA用作接收器。在标记2处,我更改了 的值vecA。现在在3处,如果我们扩展语句:fp(vecA),它变成:vecA.add(vecB)。现在我认为它应该add使用“已更改” vecA(在标记2vecA处更改)调用函数,而不是(在标记1处更改)的旧值,而是add使用“旧” 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}

*/


白板的微信
浏览 188回答 2
2回答

白猪掌柜的

现在我认为它应该使用“更改”的 vecA 调用 add 函数不,这种想法是错误的。fp 是并且保持绑定到旧值。

largeQ

在您的第一个示例中, fp 使用 vecA 的值,因此 vecA 发生的任何事情都不会在初始分配后反映在 fp 中。在您的第二个示例中, fp 使用 vecA 的地址。现在您将内存位置中的 vecA 的值传递给 add func() 以便它使用更新的值。
随时随地看视频慕课网APP

相关分类

Go
我要回答