地方エンジニアの学習日記

興味ある技術の雑なメモだったりを書いてくブログ。たまに日記とガジェット紹介。

【Go】ネストされた構造体の値を書き変える

stackoverflow.com

ここの内容は大体上で言ってることとなってます。

type P1 struct {
    list *[]P2
}

type P2 struct {
    node int
}

P1がP2のスライスへのポインタを持っている場合にP1のレシーバでP2が持つ値を書き換える方法。割とハマったのでメモ。

package main

import (
    "fmt"
)

func (p1 *P1) New() {
    for k, v := range *h.list {
        (*h.list)[i].node = 20
    }
}

*members[0]は、コンパイラーによって*(members [0])と解釈されてしまうというのがハマりポイントで

代入部分を以下のように書いてしまうとh.list[i].nodeというポインタが指す場所を書き換えようとするような動作になってしまいコンパイルエラーとなる。for rangeのrangeの返り値には同じ参照先が使用されているみたいなのは多言語から来たのでなかなかにハマりポイント。

*h.list[i].node = 20

今回に関してはCでも多分同じような話があるけどまあ優先順位あたりはきちんと把握しておこうという結論。

ポインタのスライスならもう少し簡単。要素を呼び出し先で動的にいじるみたいな実装をするときにつかえる。

type P1 struct {
    p []*P2
}

type P2 struct {
    age int
}

func ch(pp *P1) {
    for i, _ := range pp.p {
        pp.p[i].age = 2
    }
}