Memory Leaking Scenarios -Go 101
文中提到的substring和string公用底层的结构。但是如果我们之间打印substring和string的指针地址,会发现其实两者并不一样。
其实原因是string在golang的实际实现是reflect.StringHeader。同理slice的实际实现是*reflect.SliceHeader。因此比较两个string的地址应该用如下方式:
x := "x"
y1 := x[0:1]
sh := (*reflect.StringHeader)(unsafe.Pointer(&x))
ch := (*reflect.StringHeader)(unsafe.Pointer(&y1))
fmt.Println(sh.Data, ch.Data)
x1 := []int{12}
y2 := x1[0:1]
xr := (*reflect.SliceHeader)(unsafe.Pointer(&x1))
yr := (*reflect.SliceHeader)(unsafe.Pointer(&y2))
fmt.Printf("%v,%v,%v\n", xr.Data, yr.Data, len(x1))
这样可以看到打印出来的结果是相同的。
Go unsafe.Pointer uintptr原理和玩法