Structures in Go are copied by value (deep copy at the first level, nested structures are copied by the same rule), while slices are copied by value, but only the structure is copied, not the underlying data array: both the original and the copy of the slice point to the same backing array, so changes through one slice will be reflected in the other unless you make an explicit copy of the array using copy().
Example of copying a slice:
s1 := []int{1,2,3} s2 := s1 // pointers to the same buffer! s2[0] = 99 fmt.Println(s1) // [99 2 3] // To copy the array: s3 := make([]int, len(s1)) copy(s3, s1) s3[0] = 42 fmt.Println(s1) // [99 2 3], s3 is independent
When copying structures: if the structure contains a pointer field or a slice field, only the references are copied, not the values.
What is the way to "clone" a slice so that its changes do not affect the original?
Potentially misleading answer: Just do b := a. Correct:
copy, create a new slice of the required length and copy the data:newS := make([]int, len(a)) copy(newS, a)
Story
Description: When generating database queries, fields of the slice in the request structure were dynamically modified without making copies. When repeating queries, the data overlapped, yielding incorrect results for users.
Story
Description: When processing data in parallel, a copy of the structure was created through assignment and a slice was expanded in one goroutine while simultaneously using another original slice. Data was "overwritten", leading to unpredictable bugs.
Story
Description: Used a buffer structure, simultaneous copying through assignment did not take into account nested slices (shallow copy), changes in one place affected another buffer — ultimately it was difficult to track the source of data changes.