在golang中打印切片的地址

Jef*_*ang 2 arrays pointers go slice

我在golang上很新.在这里,我有一个问题困惑了我一段时间.我知道我们应该使用"&"来获取地址,但如果我们在没有"&"的切片上使用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)

}
Run Code Online (Sandbox Code Playgroud)

结果在我的MacBook上是这样的:

片的地址0x11354d0

片的地址0x1128be0

先感谢您!

icz*_*cza 6

Go中的切片是类似结构的小型数据结构,指向实际保存切片元素的后备数组.切片头可以使用以下类型建模reflect.SliceHeader:

type SliceHeader struct {
        Data uintptr
        Len  int
        Cap  int
}
Run Code Online (Sandbox Code Playgroud)

引用fmt动词的包文档%p:

印刷:

动词:

切片:

%p    address of 0th element in base 16 notation, with leading 0x
Run Code Online (Sandbox Code Playgroud)

指针:

%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.
Run Code Online (Sandbox Code Playgroud)

所以确实,传递一个切片值用于%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])
Run Code Online (Sandbox Code Playgroud)

输出将是(在Go Playground上尝试):

address of slice 0x170460 
address of slice 0x17d0b8 
0x170460
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,&slice[0]是相同的值%pslice.

现在让我们修改示例以使用我们自己的后备数组:

var arr = [4]int{1, 2, 3, 4}
var slice = arr[:]
Run Code Online (Sandbox Code Playgroud)

所以这样我们也可以打印支持数组的第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])
Run Code Online (Sandbox Code Playgroud)

输出(在Go Playground上试试):

address of slice 0x170460 
address of slice 0x183e78 
0x170460
Array 0th: 0x170460
Run Code Online (Sandbox Code Playgroud)

是的,后备数组的第0个元素的地址确实与切片的第0个元素的地址相同,这与slice%p动词传递时打印的值相同.