2012-10-07 6 views
15

mi ha recentemente prendere il Go, e ora ho confuso con il seguente codice:Re-affettare in 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) 
} 

E il risultato:

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] 

Qualsiasi aiuto sarebbe grazie.

+0

Le fette con la loro capacità stanno arrivando (vai 1.2). Vedi [la mia risposta sotto] (http://stackoverflow.com/a/18911267/6309) – VonC

risposta

20

c è una sezione prelevata dall'array b. Questa non è una copia, ma solo una finestra sui primi due elementi di b.

Poiché b ha una capacità di 5, c potrebbe essere esteso per prendere gli altri 3 posti (in effetti crea una nuova fetta ma nello stesso posto in memoria).

La capacità massima della fetta è la capacità della matrice sottostante meno la posizione dell'inizio della fetta nella matrice:

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

Forse questo programma renderà più chiaro che ced sono solo finestre oltre 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) 
} 

uscita:

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

Grazie per la risposta utile. – Coder

+1

Quindi anche la b avrà effetto? – Coder

+1

Sì. Ma non lo vedrai perché la lunghezza è 0. –

11

Si noti che in vai 1.2 (Q4 2013, 1.2rc1 is available now), è possibile associare a una slice una capacità propria (anziché una capacità dedotta dall'array sottostante).

Vedere "Three-index slices" e design document.

Un'operazione di affettatura crea una nuova fetta descrivendo una sezione contigua di un array o fetta già creato:

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

La capacità della fetta è il numero massimo di elementi che la fetta può trattenere, anche dopo la riscrittura; riflette la dimensione dell'array sottostante.
In questo esempio, la capacità della variabile fetta è 8.

(capacità della matrice sottostante meno la posizione dell'inizio della fetta nell'array)

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

Go 1.2 aggiunge una nuova sintassi per consentire un'operazione di divisione a specificare la capacità e la lunghezza.
Un secondo punto due introduce il valore della capacità, che deve essere inferiore o uguale alla capacità della sezione o matrice sorgente, regolata per l'origine.

Ad esempio,

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) 

imposta la fetta di avere la stessa lunghezza come nell'esempio precedente ma la sua capacità è ora solo 4 elementi (6-2).
È impossibile utilizzare questo nuovo valore di sezione per accedere agli ultimi due elementi dell'array originale.

L'argomento principale è quello di dare ai programmatori un maggiore controllo sul append.

a[i : j : k] 

Tale porzione è composta:

  • indici partendo da 0
  • lunghezza uguale a j - i
  • capacità pari a k - i

Il panico valutazione se i <= j <= k <= cap(a) non è vero.