In Golang, slices is the data type that wrap arrays to give a more general, powerful, and convenient interface to sequences of data. Except for items with explicit dimension such as transformation matrices, most array programming in Go is done with slices rather than simple arrays. In Go language, you are allowed to pass a slice to a function, means the function gets the copy of the slice. The slice, its capacity, and length are passed as parameters to a function, and the slice's pointer is always set to point to the underlying array. Therefore, if we modify the slice that is passed to the function as a value, the modified slice will also present in the slice that is present outside the function.
Example 1: Pass slice as parameter and modify the original slice
The example below shows how to modify the original slice by pass it as parameter to a function:
package main
import "fmt"
// modify the element
func modifySliceFunc(slice []int) {
if len(slice) > 0 {
slice[0] = 1000000
}
}
func main() {
slice1 := []int{1, 2, 3, 4, 5}
fmt.Println("Original slice: ", slice1)
// Passing the slice to the function
modifySliceFunc(slice1)
fmt.Println("Final slice:", slice1)
}
Output:
Original slice: [1 2 3 4 5]
Final slice: [1000000 2 3 4 5]
In the example above, slice from an array will have the array's memory location, so changing the value of the slice will affect the array value
Example 2: Pass a slice as parameter function and changing its size
Here is an example of passing a slice as parameter and using append to change the slice's size:
package main
import "fmt"
// modify the element
func modifySliceFunc(slice []int) {
slice = append(slice, 10202020)
fmt.Println("Slice inside the function: ", slice)
}
func main() {
slice1 := []int{1, 2, 3, 4, 5}
fmt.Println("Original slice: ", slice1)
// Passing the slice to the function
modifySliceFunc(slice1)
fmt.Println("Final slice:", slice1)
}
Output:
Original slice: [1 2 3 4 5]
Slice inside the function: [1 2 3 4 5 10202020]
Final slice: [1 2 3 4 5]
Noted that slice is a dynamically-sized, flexible view into the elements of an array. So in the example below, if we change the size of the slice, the array will no longer be affected because new slice will be allocated and no longer have the same pointer to the original slice.
Example 3: Pass a slice as parameter function and return another slice
If you want to write a function to take a slice as an argument and changing the the slice's size, you can return an slice and then assign it to the original slice variable. Here is an example of writing a function that changing the slice's array:
package main
import "fmt"
// modify the element
func modifySliceFunc(slice []int) []int {
slice = append(slice, 10202020)
fmt.Println("Slice inside the function: ", slice)
return slice
}
func main() {
slice1 := []int{1, 2, 3, 4, 5}
fmt.Println("Original slice: ", slice1)
// Passing the slice to the function
slice1 = modifySliceFunc(slice1)
fmt.Println("Final slice:", slice1)
}
Output:
Original slice: [1 2 3 4 5]
Slice inside the function: [1 2 3 4 5 10202020]
Final slice: [1 2 3 4 5 10202020]
Example 4: Pass a pointer to a slice as parameter function
With the same purpose to append or other operation which would cause resizing, we can pass a pointer of slice to a function. Let's take a look at example below:
package main
import "fmt"
// modify the element
func modifySliceFunc(slice *[]int) {
*slice = append(*slice, 10202020)
fmt.Println("Slice inside the function: ", slice)
}
func main() {
slice1 := []int{1, 2, 3, 4, 5}
fmt.Println("Original slice: ", slice1)
// Passing the slice to the function
modifySliceFunc(&slice1)
fmt.Println("Final slice:", slice1)
}
Output:
Original slice: [1 2 3 4 5]
Slice inside the function: &[1 2 3 4 5 10202020]
Final slice: [1 2 3 4 5 10202020]
Summary
The four examples above show how to pass slice as function parameter. The slice will change inside and outside the function. Another thing to remember from this lesson is that you can pass a slice if you are only changing its value without appending or performing any other operations that would result in resizing. If not, you should think about passing a slice pointer.
References
https://go.dev/doc/effective_go#slices
Pass slice as function argument, and modify the original slice