2016-04-19 2 views
9

Скажем, у меня есть следующий массив целых чисел длины 3:Как получить базовый массив среза в Go?

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

Тогда я захватить кусочек только первых двух пунктов

numSlice := nums[:2]

Вызов cap на numSlice и Nums дает 3 в обоих случаях, а len дает 2 и 3 соответственно.

Если я затем присоединяюсь к этому фрагменту (numSlice = append(numSlice, 10)), базовый массив (nums) теперь [1 2 10]. cap остается на уровне 3 для обоих, как основной массив среза то же самое, и Len для среза теперь 3.

Однако, если я снова (numSlice = append(numSlice, 20)) добавить в ту часть, лежащая в основе массива среза должен измениться - мы видим, что это так, когда cap теперь удвоился для numSlice, а теперь сейчас нет.

Извините за чрезмерное объяснение, просто пройдя через него, но кто-нибудь может объяснить мне, что происходит под капотом, базовый массив и как получить ссылку на новый массив?

ответ

13

Во-первых, если вы еще этого не сделали, вы должны прочитать this official blog post about slice internals. Это должно прояснить все.

Теперь, чтобы получить доступ к базовому массиву, вы можете использовать комбинацию reflect и unsafe. В частности, reflect.SliceHeader содержит поле Data, которое содержит указатель на базовый массив среза.

Пример заимствован из документации unsafe пакета:

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

этот пост полезно также: http://blog.golang.org/slices – leeor

+2

Стоит отметить, что 'Data' не может указывать на начало массива поддержки: только до 0-го элемента среза. Таким образом, в случае 'numSlice: = nums [1:]' он фактически будет указывать на второй элемент массива. [Пример] (http://play.golang.org/p/8fCCz9d7rG) – djd

+0

Как возможно, глупый вопрос, какова была бы производительность? – Highstead

Смежные вопросы