2010-11-19 17 views
5

Después de leer lo siguiente en http://golang.org/doc/effective_go.html#arrays ...Tratamiento de matrices en Ir

  • Las matrices son valores. Al asignar una matriz a otra, se copian todos los elementos .
  • En particular, si se pasa una matriz a una función, que recibirán una copia de la matriz, no un puntero a ella.

... espero en el código siguiente al arr2 a ser distinto de arr y main() 's arr a ser distinto de shuffle()' s arr. ¿Puede alguien explicar por qué el siguiente código se mezcla al arr2? Sé que Go sigue siendo un lenguaje joven; tal vez el tratamiento de las matrices ha cambiado?

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

Nota: el 'shuffle()' función debe utilizar 'j: = rand.Intn (i + 1)' demás se excluye la probabilidad de que un elemento de permanecer en el lugar, así por ejemplo shuffleing '{1, 2} 'siempre daría como resultado' {2, 1} 'y nunca en el otro resultado posible' {1, 2} '. – icza

Respuesta

20

Creo que su problema es que está confundiendo las matrices y las divisiones.

Arrays son listas de longitud fija de valores. En realidad, no estás usando ninguna matriz en tu ejemplo. Las matrices se pueden declarar de varias maneras:

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 

Estás utilizando rebanadas. Una porción es una referencia a una matriz subyacente. Hay algunas formas de asignar nuevos rebanadas:

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 

cualquier otra asignación de división también acaba de duplicar una referencia a una matriz.

Ahora que hemos establecido que, la línea

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

crea una rebanada referencia a una matriz subyacente anónima que contiene los números 1-5.

arr2 := arr 

duplicados que hacen referencia - no no copian la matriz subyacente. Entonces hay una matriz subyacente y dos referencias a ella. Es por eso que los contenidos de arr2 cambian cuando modifica los contenidos de arr. Están haciendo referencia a la misma matriz.

+1

Gracias por explicarlo; tiene sentido ahora. – Timothy

Cuestiones relacionadas