Golang, указатель на функцию с получателем значения, не вызывает эту функцию с измененным получателем при повторном вызове - PullRequest
0 голосов
/ 01 апреля 2020
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 с «измененным» vecA (измененным при маркировке 2 ), а не с более старым значением vecA (при маркировке 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}
*/

Ответы [ 2 ]

1 голос
/ 01 апреля 2020

Теперь я думаю, что она должна вызывать функцию добавления с «измененным» vecA

Нет, это неправильное мышление. fp является и остается связанным со старым значением.

0 голосов
/ 05 апреля 2020

В первом примере fp работает со значением vecA, поэтому все, что происходит с vecA, не отражается в fp после первоначального присваивания.

Во втором примере fp работает с адресом vecA. Теперь вы передаете значение vecA в ячейке памяти функции add fun c (), поэтому она использует обновленное значение.

...