値レシーバーを持つ関数への関数ポインターであるGolangは、2回目に呼び出されたときに、変更されたレシーバーでその関数を呼び出しません

Abir Ganguly:
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では、レシーバーとして使用しfpadd関数で宣言して初期化しましたvecAマーキング2で、の値を変更しましたvecAここで3で、ステートメントを展開するfp(vecA)と、になりますvecA.add(vecB)今、それは(マーキング1での古い値ではなくadd、「変更」vecA(マーキング2で変更)で関数を呼び出す必要があると思いますが、「古い」(マーク1で関数を呼び出しています。これは、出力。どうして?vecAaddvecA

私は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}
*/
ジョエルジャコブ:

最初の例では、fpはvecAの値を処理するので、vecAに起こったことが最初の割り当て後のfpに反映されません。

2番目の例では、fpはvecAのアドレスで機能します。これで、メモリの場所にあるvecAの値がadd func()に渡され、更新された値が使用されます。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ