2012-07-31 16 views
41

Soy nuevo en el idioma Go. Me confundí con los tipos de datos array y slice.Ir lang array y cortar tipos de datos

a partir de documentos Go, las matrices se describen de la siguiente manera:

There are major differences between the ways arrays work in Go and C. In Go,

  • 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.
  • The size of an array is part of its type. The types [10]int and [20]int are distinct.

Funciones:

As in all languages in the C family, everything in Go is passed by value. That is, a function always gets a copy of the thing being passed, as if there were an assignment statement assigning the value to the parameter. For instance, passing an int value to a function makes a copy of the int, and passing a pointer value makes a copy of the pointer, but not the data it points to.

¿Por qué sort.Ints(arrayValue) modificar la variable pasada cuando declaró como una matriz, no como una rebanada?

Código

var av = []int{1,5,2,3,7} 

fmt.Println(av) 
sort.Ints(av) 
fmt.Println(av) 
return 

salida

[1 5 2 3 7] 
[1 2 3 5 7] 

Respuesta

31

Ver "Slices: usage and internals"

var av = []int{1,5,2,3,7} 

Eso es una porción, no una matriz.

A slice literal is declared just like an array literal, except you leave out the element count.

Eso explica por qué la función de clasificación modificará el contenido de de lo que se hace referencia por la rebanada.

Como se comenta a continuación por Kirk, sort.Ints le dará un error si le pasó una matriz en lugar de una porción.

func Ints(a []int) 
+1

Además, sort.Ints te dará un error si lo pasaste matriz en lugar de una porción. La documentación de sort.Ints especifica un sector. https://golang.org/pkg/sort/#Ints – Kirk

+0

@Kirk buen punto. Lo he incluido en la respuesta para una mayor visibilidad. – VonC

34

Debido a que usted está utilizando una rebanada, no una matriz.

Eso es una rebanada:

var av = []int{1,5,2,3,7} 

Y esas son las matrices:

var av = [...]int{1,5,2,3,7} 
var bv = [5]int{1,5,2,3,7} 

Si intenta compilar:

var av = [...]int{1,5,2,3,7} 
fmt.Println(av) 
sort.Ints(av) 
fmt.Println(av) 

, recibirá un error:

cannot use av (type [5]int) as type []int in function argument

como sort.Ints espera recibir un slice []int.

+1

Entonces, ¿un segmento es como una matriz de "referencia"? – allyourcode

+7

sí, un corte consiste en un puntero a un elemento de matriz y una longitud. Por lo tanto, es una referencia a una subsección de la matriz (una 'porción' de la matriz, si lo desea). – mfhholmes

+0

@mfhholmes gracias. Esta es la explicación más concisa en mi humilde opinión. –

10

[]int{1,5,2,3,7} no es una matriz. Una matriz tiene su longitud en su tipo, como [5]int{1,5,2,3,7}.

Haga una copia de la rebanada y ordenar su lugar:

a := []int{1,5,2,3,7} 
sortedA := make([]int, len(a)) 
copy(sortedA, a) 
sort.Ints(sortedA) 
fmt.Println(a) 
fmt.Println(sortedA) 
+3

También puede tener ... en lugar de su longitud. [...] int {1,2,3} –

+0

@ArtemShitov Bien, es un azúcar sintáctico útil. El compilador lo traducirá a '[3] int {1,2,3}' de todos modos. –

2
var av = []int{1,5,2,3,7} 

en la declaración anterior va a inicializar rebanada como un array

Para crear una matriz de la sintaxis debe ser

var av = [5]int{1,5,2,3,7}