A common way to duplicate Go slices?

Novice programmer. I need to duplicate fragments (and part of the base array) so that the caller does not mutate the original elements of the array. I think I can write a function for this for arrays of certain types:

func duplicateSliceOfSomeType(sliceOfSomeType []SomeType) []SomeType { dulicate := make([]SomeType, len(sliceOfSomeType)) copy(duplicate, sliceOfSomeType) return duplicate } 

But is there a way to create the same method in the general case, possibly without generics?

 func duplicateSlice(slice []?) []?{ duplicate := make([]?, len(slice)) copy(duplicate, slice) return duplicate } 
+6
source share
2 answers

You can write one simple statement to make a shallow copy of a slice,

 b := append([]T(nil), a...) 

Which is equivalent

 b := make([]T, len(a)) copy(b, a) 

For instance,

 package main import "fmt" type T int func main() { a := []T{4, 2} b := append([]T(nil), a...) fmt.Println(&a[0], a, &b[0], b) b[0] = 9 fmt.Println(&a[0], a, &b[0], b) } 

Output:

 0x10328000 [4 2] 0x10328020 [4 2] 0x10328000 [4 2] 0x10328020 [9 2] 

ADDITION:

General difficulties with reflection

If people are new to Go, they should not use reflection at all.

-rob

Reflection is subtle even for experts. It reveals details, understanding depends on knowing quite fundamental things about how a language works and, to a lesser extent, how it is implemented. This can be confusing even for experienced Go programmers; newly minted gophers are much more important, simple things to learn first. Those who study reflection too early confuse themselves with a cloud of their understanding of these fundamentals. It’s best to hold it in your hands until the rest of the image is transparent.

Rob

Nonetheless,

 package main import ( "fmt" "reflect" ) func CopySlice(s interface{}) interface{} { t, v := reflect.TypeOf(s), reflect.ValueOf(s) c := reflect.MakeSlice(t, v.Len(), v.Len()) reflect.Copy(c, v) return c.Interface() } type T int func main() { { // append a := []T{4, 2} b := append([]T(nil), a...) fmt.Println(&a[0], a, &b[0], b) b[0] = 9 fmt.Println(&a[0], a, &b[0], b) } { // make and copy a := []T{4, 2} b := make([]T, len(a)) copy(b, a) fmt.Println(&a[0], a, &b[0], b) b[0] = 9 fmt.Println(&a[0], a, &b[0], b) } { // reflection a := []T{4, 2} b := CopySlice(a).([]T) fmt.Println(&a[0], a, &b[0], b) b[0] = 9 fmt.Println(&a[0], a, &b[0], b) } } 

Output:

 0xc20800a200 [4 2] 0xc20800a210 [4 2] 0xc20800a200 [4 2] 0xc20800a210 [9 2] 0xc20800a290 [4 2] 0xc20800a2a0 [4 2] 0xc20800a290 [4 2] 0xc20800a2a0 [9 2] 0xc20800a310 [4 2] 0xc20800a320 [4 2] 0xc20800a310 [4 2] 0xc20800a320 [9 2] 
+20
source

You can make a copy of any type using the reflect package, in particular reflect.Copy : http://golang.org/pkg/reflect/#Copy

0
source

Source: https://habr.com/ru/post/976891/


All Articles