golang slice学习

关于获取slice相关内存地址操作

       s := make([]int, 1)
       t.Log(unsafe.Pointer(&s))// 获取当前slice 结构体实例的内存地址
       t.Log(unsafe.Pointer(&(s[0]))) // 获取底层数组第一个元素的内存地址
       t.Logf("%p\n", s)// 获取底层数组的内存地址,对于数组而言,数组是一个连续的内存空间,实际数组的内存地址就是数组内第一个元素的内存地址

  对于切片执行append操作每次都会生成新的切片实例

func TestAppendNewSlice(t *testing.T) {
	a := make([]int, 1, 5)
	t.Logf("%p", &a)
	// 新的切片实例赋值给已存在的切片实例时,实际是将slice结构体中的数组指针/长度/容量字段赋值给已存在的实例
	a = append(a, 1)
	t.Logf("%p", &a) 
	// 生成新的slice实例
	b := append(a, 1) 
	t.Logf("%p", &b) // 这里输出b指向切片实例的地址和a指向切片实例的地址是不同的
	// 当切片进行赋值操作时,实际是将b实例中的三个属性复制给a中的属性,而不是将变量a指向的内存地址改变
	a = b
	t.Logf("%p", &a)
	t.Log(len(a), len(b), cap(a), cap(b))
}

  在执行append操作时,如果未发生扩容,新的切片实例和原始切片实例指向的是相同的数组内存地址,反之,如果发生扩容操作,会生成新的数组,因此新的切片实例就会指向新的数组内存地址;

  当执行切片实例赋值操作时,新的切片实例赋值给旧的切片实例,实际是将新的切片实例中三个属性进行值赋值操作

type slice struct {
	array unsafe.Pointer
	len   int
	cap   int
}

  

posted @ 2020-08-20 15:28  郭星  阅读(176)  评论(0)    收藏  举报