2016-04-19 7 views
9

Powiedzmy mam następujący tablicę int o długości 3:Jak uzyskać ukrytą tablicę plasterka w Go?

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

Potem chwycić kawałek tylko pierwsze dwie pozycje

numSlice := nums[:2]

Wywoływanie cap na numSlice i Nums wydajność 3 w obu przypadkach i len daje odpowiednio 2 i 3.

Jeśli następnie dołączę do tego plasterka (numSlice = append(numSlice, 10)), podrzędna tablica (nums) jest teraz [1 2 10]. cap pozostaje na poziomie 3 dla obu, ponieważ podrzędna tablica plasterka jest taka sama, a len dla plasterka wynosi teraz 3.

Jednak, jeśli dołączę do tego plasterka ponownie (numSlice = append(numSlice, 20)), podstawowa tablica plasterka Musimy się zmienić - widzimy, że tak jest, gdy cap podwoiła się dla numSlice i len jest teraz 4.

Przepraszamy za przesadne wyjaśnienie, po prostu przechodząc przez to, ale czy ktoś może mi wyjaśnić, co dzieje się pod maską do podstawowej tablicy i jak uzyskać odniesienie do nowej tablicy?

Odpowiedz

13

Po pierwsze, jeśli jeszcze tego nie zrobiłeś, powinieneś przeczytać this official blog post about slice internals. To powinno wyjaśnić wszystko.

Aby uzyskać dostęp do podstawowej tablicy, można użyć kombinacji reflect i unsafe. W szczególności, reflect.SliceHeader zawiera pole Data, które zawiera wskaźnik do znajdującej się pod spodem tablicy przekroju.

Przykład zaczerpnięto z dokumentacji pakietu unsafe:

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

ten post jest zbyt pomocne: http://blog.golang.org/slices – leeor

+2

Warto zauważyć, że 'Data' nie może wskazywać na początek tablicy podkładu: tylko do 0-tego elementu plastra. Tak więc w przypadku 'numSlice: = nums [1:]' to w rzeczywistości wskazywałoby na drugi element tablicy. [Przykład] (http://play.golang.org/p/8fCCz9d7rG) – djd

+0

Być może głupie pytanie brzmiało: jak wyglądałby ten występ? – Highstead