golang中slice的注意事項
摘要:
slice本質上是基於陣列的一種資料結構(struct),是陣列的一種透視。
slice的資料結構為:
type slice struct {
array unsafe.Pointer
lenint
capint
}
請注意,...
- slice本質上是基於陣列的一種資料結構(struct),是陣列的一種透視。
- slice的資料結構為:
type slice struct { array unsafe.Pointer lenint capint }
請注意, array是一個指標型別。
- slice作為陣列的一部分透視來使用:
testArr := [5]int{0, 1, 2, 3, 4} sliceFromArr := testArr[1:3] fmt.Println(sliceFromArr)// [1, 2] sliceFromArr[0] = 11 fmt.Println(testArr)//[0 11 2 3 4] fmt.Printf("len: %d, cap: %d, data:%+v \n",len(sliceFromArr), cap(sliceFromArr), sliceFromArr) //len: 2, cap: 4, data:[11 2] //修改slice同時會修改array,因為slice中有array的指標 sliceFromArr = append(sliceFromArr, 33, 44) fmt.Println(testArr)//[0 11 2 33 44] fmt.Printf("len: %d, cap:%d, data:%+v \n", len(sliceFromArr), cap(sliceFromArr), sliceFromArr) //len: 4, cap:4, data:[11 2 33 44] //當len小於透視的陣列的length時,對slice的修改都會同時修改它透視的陣列 sliceFromArr = append(sliceFromArr, 55) fmt.Println(testArr)//[0 11 2 33 44] fmt.Printf("len: %d, cap: %d, data:%+v \n", len(sliceFromArr), cap(sliceFromArr), sliceFromArr) //len: 5, cap: 8, data:[11 2 33 44 55] //append()當len大於cap時,會重新開闢為原來slice的cap兩倍的記憶體空間,並把slice拷貝到新開闢的空間中。 //所以原來的陣列顯示的依舊是原來的記憶體地址中的資料,而現在的slice已經儲存來一個新開闢的8個int的空間中, //對slice的修改不會改動原來的陣列。
- slice單獨定義,並作為引數傳遞給函式:
func setSlice(testSlice []int){ testSlice[0] = 10 testSlice[1] = 11 } func setSliceByAppend(testSlice []int){ testSlice = append(testSlice, 22) } func setSliceByAppendPointer(testSlice *[]int){ *testSlice = append(*testSlice, 22) } func main(){ testSlice := make([]int, 2, 3) testSlice[0] = 0 testSlice[1] = 1 fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice) //len: 2, cap: 3, data:[0 1] setSlice(testSlice) fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice) //len: 2, cap: 3, data:[10 11] //因為slice中的array是指標型別所以在引數傳遞中,可以修改slice中array的值 setSliceByAppend(testSlice) fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice) //len: 2, cap: 3, data:[10 11] setSliceByAppendPointer(&testSlice) fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice) //len: 3, cap: 3, data:[10 11 22] //由setSliceByAppend和setSliceByAppendPointer的測試可以得知, //使用append()來修改slice的值,會生成一個新的slice,新的slice記憶體地址和原來的就不一樣了。 //如果需要使用append()來修改slice的值,需要使用指標型別的slice。 }