Reputation: 55
The following code
package main
import "fmt"
func main() {
type Recording struct {
Heartbeat string `json:"heartbeat"`
Videos []string `json:"videos,omitempty"`
}
recordings := []Recording{}
recordings = append(recordings, Recording{Heartbeat: "Blue", Videos: []string{"Foo"}})
for _, recording := range recordings {
recording.Videos[0] = "Bar"
}
fmt.Println(recordings)
}
outputs
[{Blue [Bar]}]
and not
[{Blue [Foo]}]
This means that the array in the temporarily created recording object actually gets shallow-copied and modifies the original array, although that might not be programmer's intention. This can lead to unintended bugs.
Is there a way to do deep copy on a range loop for slices.
Upvotes: 0
Views: 705
Reputation: 1196
This is because slices are pointers to underlying arrays, so you need to implement your own deep copy function if you need a separate copy of the data.
Here is your example updated to make a copy of recordings
:
package main
import "fmt"
func main() {
type Recording struct {
Heartbeat string `json:"heartbeat"`
Videos []string `json:"videos,omitempty"`
}
recordings := []Recording{}
recordings = append(recordings, Recording{Heartbeat: "Blue", Videos: []string{"Foo"}})
// Make a copy
other := make([]Recording, len(recordings))
for i, r := range recordings {
other[i] = Recording{
Heartbeat: r.Heartbeat,
Videos: append([]string{}, r.Videos...),
}
}
for _, recording := range other {
recording.Videos[0] = "Bar"
}
fmt.Println(recordings)
fmt.Println(other)
}
Output:
[{Blue [Foo]}]
[{Blue [Bar]}]
Upvotes: 0