1. 程式人生 > 實用技巧 >golang slice學習

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
}