2016-04-19 26 views
9

Diciamo che ho il seguente array di int di lunghezza 3:Come ottenere l'array sottostante di una sezione in Go?

nums := [3]int{1,2,3}

Poi ho afferrare la fetta di appena le prime due voci

numSlice := nums[:2]

Invocare cap su numSlice e nums cede 3 in entrambi i casi, e len rese 2 e 3 rispettivamente.

Se poi aggiungo a quella sezione (numSlice = append(numSlice, 10)), l'array sottostante (nums) è ora [1 2 10]. cap rimane a 3 per entrambi, poiché l'array sottostante della sezione è lo stesso e len per la sezione è ora 3.

Tuttavia, se aggiungo nuovamente quella sezione (numSlice = append(numSlice, 20)), l'array sottostante della sezione dobbiamo vedere che questo è il caso quando cap ora è raddoppiato per numSlice e len è ora 4.

Scusate per la spiegazione esagerata, semplicemente camminandoci attraverso, ma qualcuno può spiegarmi cosa succede sotto il cofano a l'array sottostante e come ottenere il riferimento al nuovo array?

risposta

13

In primo luogo, se non lo si è già, è necessario leggere this official blog post about slice internals. Questo dovrebbe chiarire tutto.

Ora per accedere all'array sottostante, è possibile utilizzare una combinazione di reflect e unsafe. In particolare, reflect.SliceHeader contiene un campo Data che contiene un puntatore all'array sottostante di una sezione.

Esempio adattato dalla documentazione del pacchetto unsafe:

s := []int{1, 2, 3, 4} 
hdr := (*reflect.SliceHeader)(unsafe.Pointer(&s)) 
data := *(*[4]int)(unsafe.Pointer(hdr.Data)) 
+4

questo post è utile anche: http://blog.golang.org/slices – leeor

+2

Da segnalare che il 'data' potrebbe non puntare al inizio del backing array: solo per l'elemento 0-esimo della fetta. Quindi, nel caso di 'numSlice: = nums [1:]' in realtà finirà per puntare al secondo elemento della matrice. [Esempio] (http://play.golang.org/p/8fCCz9d7rG) – djd

+0

Come una domanda forse stupida, quale sarebbe la performance su questo? – Highstead