开发者

Treatment of Arrays in Go

开发者 https://www.devze.com 2023-01-25 16:59 出处:网络
Having read the following at http://golang.org/doc/effective_go.html#arrays... Arrays are values. Assigning one array to another copies all the

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 exp开发者_JAVA技巧ect 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)
        }
}


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号