Arrays in Go have two relevant properties:

  • They have a fixed size; [5]int is is distinct from [3]int.
  • They are value types. Consider this example:
package main

import "fmt"

func main() {
  var a [5]int
  b := a
  b[2] = 7
  fmt.Println(a, b) // prints [0 0 0 0 0] [0 0 7 0 0]

The statement b := a declares a new variable, b, of type [5]int, and copies the contents of a to b. Updating b has no effect on the contents of a because a and b are independent values.


Go’s slice type differs from its array counterpart in two important ways:

  • Slices do not have a fixed length.
  • Assigning one slice variable to another does not make a copy of the slices contents.

The slice header value

package runtime

type slice struct {
  ptr   unsafe.Pointer
  len   int
  cap   int

This is important because unlike map and chan types slices are value types and are copied when assigned or passed as arguments to functions.

package main

import "fmt"

func double(s []int) {
  s = append(s, s...)

func main() {
  s := []int{1, 2, 3}
  fmt.Println(s, len(s)) // prints [1 2 3] 3


package main

import (

func binaryTreePaths() {
	res := make([]string, 0, 16)
	fmt.Printf("before %+v \n", res)
	fmt.Printf("after %+v \n", res)

	header := (*reflect.SliceHeader)(unsafe.Pointer(&res))
	header.Len = 1
	fmt.Printf("after trick %+v \n", res)

func dfs(res []string) {
	res = append(res, "10")
	fmt.Printf("res in dfs %+v \n", res)

func main() {