2012-10-07 30 views
15

Recientemente ha recoger el Go, y ahora confundido con el siguiente código:Re-cortar en Golang

package main 

import "fmt" 

func main() { 
    a := make([]int, 5) 
    printSlice("a", a) 
    b := make([]int, 0, 5) 
    printSlice("b", b) 
    c := b[:2] 
    printSlice("c", c) 
    d := c[2:5] 
    printSlice("d", d) 
} 

func printSlice(s string, x []int) { 
    fmt.Printf("%s len=%d cap=%d %v\n", 
     s, len(x), cap(x), x) 
} 

Y el resultado:

a len=5 cap=5 [0 0 0 0 0] 
b len=0 cap=5 [] 
c len=2 cap=5 [0 0] //why the capacity of c not 2 but 5 instead 
d len=3 cap=3 [0 0 0] 

cualquier ayuda se agradece.

+0

Están llegando rebanadas con su propia capacidad (vaya 1.2). Ver [mi respuesta a continuación] (http://stackoverflow.com/a/18911267/6309) – VonC

Respuesta

20

c es una porción tomada de la matriz b. Esto no es una copia, sino solo una ventana sobre los 2 primeros elementos de b.

Como b tiene una capacidad de 5, c podría extenderse para ocupar los otros 3 lugares (de hecho, hace una nueva porción pero sobre el mismo lugar en la memoria).

La capacidad máxima de la rebanada es la capacidad de la matriz subyacente menos la posición del inicio de la rebanada de la matriz:

array : [0 0 0 0 0 0 0 0 0 0 0 0] 
array : <---- capacity ---> 
slice :  [0 0 0 0] 
slice :  <---- capacity ---> 

Tal vez este programa hará que sea más claro que cyd son sólo ventanas sobre b:

func main() { 
    b := make([]int, 0, 5) 
    c := b[:2] 
    d := c[1:5] // this is equivalent to d := b[1:5] 
    d[0] = 1 
    printSlice("c", c) 
    printSlice("d", d) 
} 

salida:

c len=2 cap=5 [0 1] // modifying d has modified c 
d len=4 cap=4 [1 0 0 0] 
+2

Gracias por la útil respuesta. – Coder

+1

Entonces, ¿el b también se verá afectado? – Coder

+1

Sí. Pero no lo verás porque la longitud es 0. –

11

Nótese que en vaya 1.2 (Q4 2013, 1.2rc1 is available now), , puede asociar a una división una capacidad propia (en lugar de una capacidad deducida de la matriz subyacente).

Ver "Three-index slices", y el design document.

Una operación de corte crea un nuevo segmento mediante la descripción de una sección contigua de una matriz o rebanada ya creado:

var array [10]int 
slice := array[2:4] 

La capacidad de la rebanada es el número máximo de elementos que la rebanada puede contenerse, incluso después de la creación de un rescoldo; refleja el tamaño de la matriz subyacente.
En este ejemplo, la capacidad de la variable rebanada es 8.

(capacidad de la matriz subyacente menos la posición del inicio de la rebanada en la matriz)

array : [0 0 0 0 0 0 0 0 0 0] 
array : <---- capacity ---> 
slice : [0 0] 
slice : <-- capacity --> 8 (10-2) 

Go 1.2 agrega nueva sintaxis para permitir una operación de corte a especifique la capacidad, así como la longitud.
Un segundo signo de dos puntos introduce el valor de la capacidad, que debe ser menor o igual a la capacidad del segmento o matriz de origen, ajustado para el origen.

Por ejemplo,

slice = array[2:4:6] 

array : [0 0 0 0 0 0 0 0 0 0] 
array : <---- capacity ---> 10 
slice : [0 0] 
slice : <- cap->   4 (6-2) 

coloca la rebanada de tener la misma longitud que en el ejemplo anterior, pero su capacidad es ahora sólo 4 elementos (6-2).
Es imposible utilizar este nuevo valor de sector para acceder a los dos últimos elementos del conjunto original.

El argumento principal es dar a los programadores más control sobre append.

a[i : j : k] 

esa rebanada tiene:

  • índices a partir de 0
  • longitud es igual a j - i
  • capacidad es igual a k - i

Los pánicos de evaluación si i <= j <= k <= cap(a) no es cierto.