Recently I began to learn the programming language Golang, I didn’t really like the beginning, but it was necessary to work, after programming in Java a bit complicated.
A couple of questions appeared, in the Golang language, simple types are passed by value, arrays also belong to a simple type, maps and slices are passed by reference, I understood the structures, you can transfer both by reference and by value, it all depends on the developer, but I often stumble for examples in nete where slices and maps are transmitted by taking an address, why it is necessary, if by default they still come back like that, especially if you pass the slice explicitly by reference, then it can no longer be iterated if I misunderstood something explain very little documentation on russ th.

    1 answer 1

    In golang, there is no parameter passing by reference — parameters are always passed by value, i.e. are copied. The & operator is taking the address of a variable, i.e. passing a pointer, not passing a parameter by reference, i.e. as a special case, pointers are passed by value. map, slice are also passed by value, they just have pointers inside them and they copy the pointers, not the contents of the table / slice.

    The easiest way to demonstrate this is by the example of slice. Inside the slice is the soot structure: https://github.com/golang/go/blob/master/src/runtime/slice.go

    type slice struct { array unsafe.Pointer len int cap int } 

    those. when passed by value, you can change the elements inside slice.array, since after copying the pointer will point to the same memory area as the original one, but changing the length or capacity of the slice will not work. More precisely, these changes will not be visible outside the called function, since the length, capacity, and (possibly) pointer of the array will change only in a copy of the slice.

    Here is a good example: https://play.golang.org/p/SpFFDdzeXR

     package main import ( "fmt" ) func f_slice_item(s []int) { s[0] = 1 } func f_slice_size(s []int) { s = append(s, 1) } func f_slice_pointer_item(s *[]int) { (*s)[0] = 3 } func f_slice_pointer_size(s *[]int) { *s = append(*s, 5) } func f_iter(s *[]int) { for i, v := range *s { fmt.Println(i, "-", v) } } func main() { var s []int fmt.Println("slice by value") s = []int{0} f_slice_item(s) fmt.Println(s) s = []int{0} f_slice_size(s) fmt.Println(s) fmt.Println() fmt.Println("slice by pointer") s = []int{0} f_slice_pointer_item(&s) fmt.Println(s) s = []int{0} f_slice_pointer_size(&s) fmt.Println(s) fmt.Println() fmt.Println("iter") f_iter(&s) } 

    Result of performance:

     slice by value [1] [0] slice by pointer [3] [0 5] iter 0 - 0 1 - 5 
    • Thank you very much, and then how to iterate on a slice, if you pass its address to a function? - El Salvadore
    • You can simply * add a name in front of the variable name with a pointer inside the function - it is called unnamed. Completed the answer. - rekby