構造体のスライスから要素を削除する (解決済み)
提供されたコード スニペットでは、構造体を削除しようとすると問題が発生します。値レシーバーを使用して、構造体内のスライスから要素を取得します。これにより、元の構造体のスライスが誤って変更されます。
これを解決するには、スライスを変更するメソッドでポインタ レシーバを使用する必要があります。これは、Go 値レシーバーがレシーバー値のコピーを作成するためです。つまり、メソッド内でレシーバーに加えられた変更は元の構造体に反映されません。
修正されたコードは次のとおりです:
func (guest *Guest) removeFriend(id int) { for i, other := range guest.friends { if other == id { guest.friends = append(guest.friends[:i], guest.friends[i+1:]...) break } } }
ポインター レシーバー (*Guest) を使用することにより、メソッドは元の Guest 構造体のフレンド スライスを変更し、要素が確実に削除されるようにします。
説明:
スライスが値によって渡されると、受信側メソッドはスライスのコピーを操作します。スライスに変更を加えた場合、変更はコピーにのみ反映され、元のスライスには反映されません。ただし、ポインタ レシーバを使用すると、レシーバが元の構造体へのポインタになるため、メソッドで元のスライスを変更できます。
使用例:
guest := &Guest{ id: 1, name: "Bob", surname: "Pats", friends: []int{1, 2, 3, 4, 5}, } fmt.Println(guest) guest.removeFriend(3) fmt.Println(guest)
出力:
&{1 Bob Pats [1 2 3 4 5]} &{1 Bob Pats [1 2 4 5]}
以上が値レシーバーを使用すると、Go 構造体で不正なスライス変更が発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。