Лечение массивов в го - PullRequest
       4

Лечение массивов в го

5 голосов
/ 19 ноября 2010

Прочитав следующее в http://golang.org/doc/effective_go.html#arrays...

  • Массивы являются значениями.Присвоение одного массива другому копирует все элементы.
  • В частности, если вы передадите массив функции, он получит копию массива, а не указатель на него.

... Я ожидаю, что в следующем коде arr2 будет отличаться от arr, а main() arr будет отличаться от shuffle() * arr.Может кто-нибудь объяснить, почему следующий код тасует arr2?Я знаю, что Го все еще молодой язык;возможно, обработка массивов изменилась?

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)
        }
}

1 Ответ

20 голосов
/ 19 ноября 2010

Я думаю, что ваша проблема в том, что вы путаете массивы и фрагменты.

Массивы - это списки значений фиксированной длины. Вы на самом деле не используете никаких массивов в вашем примере. Массивы могут быть объявлены несколькими способами:

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

Вы используете ломтики. Срез - это ссылка на базовый массив. Есть несколько способов выделить новые фрагменты:

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

Любые другие назначения срезов просто дублируют ссылку на массив.

Теперь, когда мы это установили, строка

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

создает срез, ссылающийся на анонимный базовый массив, который содержит числа 1-5.

arr2 := arr

дублирует эту ссылку - не копирует базовый массив. Так что есть один базовый массив и две ссылки на него. Вот почему содержимое arr2 изменяется, когда вы изменяете содержимое arr. Они ссылаются на один и тот же массив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...