我对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)
}
结果在我的MacBook上是这样的:
切片 0x11354d0 的地址 切片的地址 0x1128be0
提前谢谢!
答案 0 :(得分:6)
Go中的切片是类似结构的小型数据结构,指向实际上包含切片元素的后备数组。切片标头可以使用reflect.SliceHeader
类型建模:
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
从fmt
的打包文档中引用动词%p
:
打印:
动词:
切片:
%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个元素)的地址,以及为{{1}传递&slice
时的地址。 },它将打印切片头的地址(因为%p
已经是一个指针值)。
要进行验证,请同时明确显示第0个元素的地址:
&slice
输出将是(在Go Playground上尝试):
fmt.Printf("address of slice %p \n", slice)
fmt.Printf("address of slice %p \n", &slice)
fmt.Println(&slice[0])
如您所见,address of slice 0x170460
address of slice 0x17d0b8
0x170460
与&slice[0]
的{{1}}相同。
现在让我们修改示例以使用我们自己的支持数组:
%p
这样,我们还可以打印支持数组的第0个元素的地址:
slice
输出(在Go Playground上尝试):
var arr = [4]int{1, 2, 3, 4}
var slice = arr[:]
是的,支持数组的第0个元素的地址确实与切片的第0个元素的地址相同,当传递给{{1时,该值与为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])
打印的值相同}}动词。