Распечатать адрес среза в Голанге - PullRequest
0 голосов
/ 18 сентября 2018

Я очень новичок на Голанге. Здесь у меня один вопрос смущал меня некоторое время. Я знаю, что мы должны использовать «&» для получения адреса, но что если мы используем printf на слайсе без «&»?

package main

import "fmt"

var slice = []int{1, 2, 3, 4}

func main() {

   fmt.Printf("address of slice %p \n", slice)

   fmt.Printf("address of slice %p \n", &slice)

}

Результат такой на моем MacBook:

адрес среза 0x11354d0

адрес среза 0x1128be0

Заранее спасибо!

1 Ответ

0 голосов
/ 18 сентября 2018

Срезы в Go - это небольшие структурные структуры данных, указывающие на резервный массив, который фактически содержит элементы среза. Заголовки срезов можно моделировать с помощью типа reflect.SliceHeader:

type SliceHeader struct {
        Data uintptr
        Len  int
        Cap  int
}

Цитирование из пакета документов fmt, глагол %p:

Печать:

Глаголы:

Slice:

%p    address of 0th element in base 16 notation, with leading 0x

Указатель:

%p    base 16 notation, with leading 0x
The %b, %d, %o, %x and %X verbs also work with pointers,
formatting the value exactly as if it were an integer.

Таким образом, при передаче значения среза для глагола %p печатается адрес 0-го элемента, который является 0-м элементом массива поддержки, и когда вы передаете &slice для %p, это будет печатать адрес заголовка слайса (поскольку &slice уже является значением указателя).

Для проверки также явно напечатайте адрес 0-го элемента:

fmt.Printf("address of slice %p \n", slice)
fmt.Printf("address of slice %p \n", &slice)
fmt.Println(&slice[0])

Вывод будет (попробуйте на Go Playground ):

address of slice 0x170460 
address of slice 0x17d0b8 
0x170460

Как видите, &slice[0] - это то же значение, что и %p для slice.

Теперь давайте изменим пример для использования нашего собственного резервного массива:

var arr = [4]int{1, 2, 3, 4}
var slice = arr[:]

Таким образом, мы также можем напечатать адрес 0-го элемента массива поддержки:

fmt.Printf("address of slice %p \n", slice)
fmt.Printf("address of slice %p \n", &slice)
fmt.Println(&slice[0])
fmt.Printf("Array 0th: %p", &arr[0])

Вывод (попробуйте на Go Playground ):

address of slice 0x170460 
address of slice 0x183e78 
0x170460
Array 0th: 0x170460

И да, адрес 0-го элемента массива резервирования действительно совпадает с адресом 0-го элемента среза, что соответствует значению, напечатанному для slice при передаче для глагола %p.

...