1、小问题
- 注意
- nil问题,renums的array指向的是实际存在的空数组地址,nums指向的是nil
func main() { var nums []int renums := make([]int, 0) if nums == nil { fmt.Println("nums is nil.") } if renums == nil { fmt.Println("renums is nil.") } } //output nums is nil.- 容量问题
- Slice array 指向所引用的 Array。因此在 Slice 上的变更。会直接修改到原始 Array 上(两者所引用的是同一个)
- 假设插入后,原本数组的容量就超过最大值了,这时候内部就会重新申请一块内存空间,将原本的元素拷贝一份到新的内存空间上。此时其与原本的数组就没有任何关联关系了,再进行修改值也不会变动到原始数组。
2、slice使用fmt.Printf("i:%p\n",i)
func main() {
i := []int{1,2,3}
fmt.Printf("i:%p\n",i)
fmt.Println("i[0]:",&i[0])
}
//outpu
i:0xc04205e0c0
i[0]: 0xc04205e0c0
-
可以看出来使用%p输出的内存地址与slice的第一个元素的地址是一样的
-
源码,可以看出来,slice获取指针是获取struct里面的指向底层数组的Data
//fmt.Printf p
func (p *pp) fmtPointer(value reflect.Value, verb rune) {
var u uintptr
switch value.Kind() {
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
u = value.Pointer()
}
switch verb {
case 'p':
p.fmt0x64(uint64(u), !p.fmt.sharp)
}
}
//获取指针
func (v Value) Pointer() uintptr {
k := v.kind()
switch k {
case Slice:
return (*SliceHeader)(v.ptr).Data
}
panic(&ValueError{"reflect.Value.Pointer", v.kind()})
}