2010-11-19 17 views
5

Po przeczytaniu poniższych w http://golang.org/doc/effective_go.html#arrays ...Leczenie tablic w Go

  • Tablice są wartości. Przypisanie jednej tablicy do drugiej powoduje skopiowanie wszystkich elementów .
  • W szczególności, jeśli przekażesz tablicę do funkcji, otrzymasz kopię tablicy, a nie wskaźnik do niej.

... Spodziewam się, w poniższym kodzie że arr2 należy odróżnić od arr i main() 's arr należy odróżnić od shuffle()' s arr. Czy ktoś może wyjaśnić, dlaczego poniższy kod tasuje się pod numerem arr2? Wiem, że Go to wciąż młody język; może zmieniło się traktowanie tablic?

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

Uwaga: twoja funkcja 'shuffle()' powinna używać 'j: = rand.Intn (i + 1)' else wykluczasz prawdopodobieństwo, że element pozostanie na miejscu, więc na przykład tasowanie '{1, 2} 'zawsze powodowałoby' {2, 1} 'i nigdy w innym możliwym wyniku' {1, 2} '. – icza

Odpowiedz

20

Myślę, że problem polega na tym, że mylicie macierze i plasterki.

Tablice są listami o stałej długości wartości. W twoim przykładzie nie używasz żadnych tablic. Tablice można zadeklarować na kilka sposobów:

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 

Używasz plasterków. Plasterek jest odniesieniem do podstawowej tablicy. Istnieje kilka sposobów na przydzielanie nowych plastrów:

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 

Wszelkie inne zadania slice są tylko powielacze odwołanie do tablicy.

Teraz, kiedy ustalono, że linia

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

tworzy kawałek odsyłania anonimowy podstawową tablicę, która zawiera numery 1-5.

arr2 := arr 

duplikaty, które odwołują się - to nie nie skopiuj podstawowy tablicę. Jest jedna podstawowa tablica i dwa odniesienia do niej. Dlatego zawartość arr2 zmienia się po modyfikacji zawartości arr. Oni odwołują się do tej samej tablicy.

+1

Dzięki za wyjaśnienie; teraz ma sens. – Timothy