Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Treatment of Arrays in Go

Tags:

arrays

go

Having read the following at http://golang.org/doc/effective_go.html#arrays...

  • Arrays are values. Assigning one array to another copies all the elements.
  • In particular, if you pass an array to a function, it will receive a copy of the array, not a pointer to it.

... I expect in the following code that arr2 to be distinct from arr, and main()'s arr to be distinct from shuffle()'s arr. Can someone please explain why the following code shuffles arr2? I know Go is still a young language; perhaps the treatment of arrays has changed?

package main

import (
        "fmt"
        "rand"
        "time"
)

func shuffle(arr []int) {
        rand.Seed(time.Nanoseconds())
        for i := len(arr) - 1; i > 0; i-- {
                j := rand.Intn(i)
                arr[i], arr[j] = arr[j], arr[i]
        }
}

func main() {
        arr := []int{1, 2, 3, 4, 5}
        arr2 := arr
        shuffle(arr)
        for _, i := range arr2 {
                fmt.Printf("%d ", i)
        }
}
like image 439
Timothy Avatar asked Nov 19 '10 02:11

Timothy


People also ask

How do you use arrays in Go?

In Go language, arrays are mutable, so that you can use array[index] syntax to the left-hand side of the assignment to set the elements of the array at the given index. You can access the elements of the array by using the index value or by using for loop. In Go language, the array type is one-dimensional.

How do you access an array element in Go?

Access Elements of an Array You can access a specific array element by referring to the index number. In Go, array indexes start at 0. That means that [0] is the first element, [1] is the second element, etc.

How do I remove an item from an array in Go?

Slices and arrays being 0-indexed, removing the n-th element of an array implies to provide input n-1. To remove the first element, call remove(s, 0), to remove the second, call remove(s, 1), and so on and so forth.

How do I slice an array in Go?

Creating a slice The syntax a[start:end] creates a slice from array a starting from index start to index end - 1 . So in line no. 9 of the above program a[1:4] creates a slice representation of the array a starting from indexes 1 through 3. Hence the slice b has values [77 78 79] .


1 Answers

I think your problem is that you're confusing arrays and slices.

Arrays are fixed-length lists of values. You're actually not using any arrays in your example. Arrays can be declared a few ways:

arr1 := [3]int{1, 2, 3}   // an array of 3 integers, 1-3
arr2 := [...]int{1, 2, 3} // same as the previous line, but we're letting
                          // the compiler figure out the size of the array
var arr3 [3]int           // a zeroed out array of 3 integers

You're using slices. A slice is a reference to an underlying array. There are a few ways to allocate new slices:

slice1 := []int{1, 2, 3}    // a slice of length 3 containing the integers 1-3
slice2 := make([]int, 3)    // a slice of length 3 containing three zero-value integers
slice3 := make([]int, 3, 5) // a slice of length 3, capacity 5 that's all zeroed out

Any other slice assignments are just duplicating a reference to an array.

Now that we've established that, the line

arr := []int{1, 2, 3, 4, 5}

creates a slice referencing an anonymous underlying array that contains the numbers 1-5.

arr2 := arr

duplicates that reference -- it does not copy the underlying array. So there's one underlying array and two references to it. That's why the contents of arr2 change when you modify the contents of arr. They're referencing the same array.

like image 58
Evan Shaw Avatar answered Sep 21 '22 02:09

Evan Shaw