slice 的底层模型为reflect.SliceHeader
// SliceHeader is the runtime representation of a slice.
// It cannot be used safely or portably and its representation may
// change in a later release.
// Moreover, the Data field is not sufficient to guarantee the data
// it references will not be garbage collected, so programs must keep
// a separate, correctly typed pointer to the underlying data.
type SliceHeader struct {
Data uintptr // 对于的底层数组的地址的整型化表示
Len int
Cap int
}
我们可以使用unsafe.Pointer
来查看
s := []byte{'h', 'e', 'l', 'l', 'o', ' ', 'w', 'o', 'r', 'l', 'd'}
sh := (*reflect.SliceHeader)(unsafe.Pointer(&s))
fmt.Printf("s : %#v\n", sh) // s : &reflect.SliceHeader{Data:0xc00000a0d0, Len:11, Cap:11}
// 截取切片
s1 := s[:5]
sh1 := (*reflect.SliceHeader)(unsafe.Pointer(&s1))
fmt.Printf("s1: %#v\n", sh1) // s1: &reflect.SliceHeader{Data:0xc00000a0d0, Len:5, Cap:11}
// append 没有超出范围,底层数组不变
s1 = append(s1, 'T')
sh1 = (*reflect.SliceHeader)(unsafe.Pointer(&s1))
fmt.Printf("s1: %#v\n", sh1) // s1: &reflect.SliceHeader{Data:0xc00000a0d0, Len:6, Cap:11}
// append超出了范围,底层数组的地址改变了
s2 := append(s, 'M')
sh2 := (*reflect.SliceHeader)(unsafe.Pointer(&s2))
fmt.Printf("s2: %#v\n", sh2) // s2: &reflect.SliceHeader{Data:0xc000014168, Len:12, Cap:24}
sh1 = (*reflect.SliceHeader)(unsafe.Pointer(&s1))
fmt.Printf("s1: %#v\n", sh1) // s1: &reflect.SliceHeader{Data:0xc00000a0d0, Len:6, Cap:11}