Go ポインタ - ポインタ経由でスライスに値を追加する 質問する

Go ポインタ - ポインタ経由でスライスに値を追加する 質問する

構造体 ProductData とスライス属性を持つそのインスタンス p があります。

type ProductInfo struct {
    TopAttributes []map[string]interface{}
}

TopAttributesを次のように設定したい

func (p *ProductInfo) setAttributeData() {
    key := "key"
    value := "value"
    setAttribute(p.TopAttributes, key, value)
}

func setAttribute(p []map[string]interface{}, key string, value interface{}) {
    val := map[string]interface{}{
        key: value,
    }
    p = append(p, val)
}

しかし、これはうまくいかないようです。

ただし、メソッドを次のように定義すると、正常に動作する別の方法があります。

   func (p *ProductInfo) setAttributeData() {
    key := "key"
    value := "value"
    p.setAttribute(key, value)
}

func (p *ProductInfo) setAttribute(key string, value interface{}) {
    val := map[string]interface{}{
        key: value,
    }
    p.TopAttributes = append(p.TopAttributes, val)
}

なぜ動作しないのかを知りたいです。コードにエラーはありませんでしたが、受信したデータは空でした。同じ方法で設定する必要がある別の BottomAttributes があるため、これを汎用関数にしようとしています。

ベストアンサー1

append追加されたスライスへの参照を返します。これは、サイズを変更する必要がある場合に、メモリ内の新しい場所を指す可能性があるためです。

最初の例では、関数に渡された変数を更新していますsetAttributeが、それだけです。その関数が終了すると、唯一の参照が失われます。

2 番目の例では、その変数が構造体内に存在し、更新されるため機能します。

最初のバージョンはポインターを使用して修正できます。

func (p *ProductInfo) setAttributeData() {
    key := "key"
    value := "value"
    setAttribute(&p.TopAttributes, key, value)
}

func setAttribute(p *[]map[string]interface{}, key string, value interface{}) {
    val := map[string]interface{}{
        key: value,
    }
    *p = append(*p, val)
}

おすすめ記事