Started learning Golang, question about Slices

I have been following Tood Mcleod’s Udemy GO course, learning a lot and it’s worth looking at if you are starting a new language. I have question with slices, I want to insert elements in the middle of a slice, but the append command also editted my previous slice. I know append adds the elements to the end of the slice. I am expecting the result slice have first part of my previous slice and the elements while keeping the previous slice intact.

x := []int{1, 2, 3, 4, 5, 6}
z := append(x[1:2], 9, 9, 9)
	
fmt.Println(x)
fmt.Println(z)
//z = append(z, x[2:]...)

output:
[1 2 9 9 9 6]
[2 9 9 9]

Jac

1 Like

For the answer to this and other slice questions:

SliceTricks.

Go Blog: Go Slices: usage and internals

Go Blog: Arrays, slices (and strings): The mechanics of ‘append’

The Go Programming Language Specification


A slice is represented by the Go runtime as a slice descriptor with a pointer to the underlying array, a length, and a capacity.

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

A slice descriptor is a window into an underlying array. Multiple slice descriptors can independently point to various subslices of the same underlying array.

Carefully track the slice descriptor pointer, length, and capacity values in the append 9, 9, 9 and append 7, 7, 7, 7, 7 examples.

Appending to and copying slices

If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array.

package main

import "fmt"

func main() {
	{
		x := []int{1, 2, 3, 4, 5, 6}
		printSlice(&x)
		y := x[1:2]
		printSlice(&y)
		z := append(y, 9, 9, 9)
		printSlice(&z)
		printSlice(&x)
	}
	fmt.Println()
	{
		x := []int{1, 2, 3, 4, 5, 6}
		printSlice(&x)
		y := x[1:2]
		printSlice(&y)
		z := append(y, 7, 7, 7, 7, 7)
		printSlice(&z)
		printSlice(&x)
	}
}

func printSlice(s *[]int) {
	fmt.Println("ptr:", &(*s)[0], "len:", len(*s), "cap:", cap(*s), "arr:", *s)
}
ptr: 0xc00009e000 len: 6 cap: 6 arr: [1 2 3 4 5 6]
ptr: 0xc00009e008 len: 1 cap: 5 arr: [2]
ptr: 0xc00009e008 len: 4 cap: 5 arr: [2 9 9 9]
ptr: 0xc00009e000 len: 6 cap: 6 arr: [1 2 9 9 9 6]

ptr: 0xc00009e030 len: 6 cap: 6 arr: [1 2 3 4 5 6]
ptr: 0xc00009e038 len: 1 cap: 5 arr: [2]
ptr: 0xc0000a8000 len: 6 cap: 10 arr: [2 7 7 7 7 7]
ptr: 0xc00009e030 len: 6 cap: 6 arr: [1 2 3 4 5 6]
1 Like