Go語言中切片作為函式引數,函式中使用append新增元素
阿新 • • 發佈:2019-01-24
切片作為函式,通過append新增元素,有可能會更改地址:
1)新增的資料元素長度超過切片引數的容量,則會另開闢空間,重新分配底層陣列,並複製資料。函式中的此切片與原切片地 址不同; 此切片指向新開闢的記憶體。函式執行結束,記憶體釋放,不會影響元切片的內容。
2)否則原切片與函式中的切片指向同一地址。會影響切片的內容。
3)切片名本身就是一個指標(內容儲存指向切片的首地址)
程式碼測試:
package main import "fmt" func main01() { s := make([]int, 3, 5) s[2] = 8888 fmt.Printf("原地址:%p", s) s = append(s, 12) fmt.Printf("\n新增資料之後的地址:%p", s) /* append新增元素,容量足夠,則在原基礎之上新增資料,地址不會發生改變 輸出: 原地址:0xc04207e030 新增資料之後的地址:0xc04207e030 */ } func main02() { s := make([]int, 3) s[2] = 666 fmt.Printf("append新增資料之前的地址:%p", s) s = append(s, 888) fmt.Printf("\nappend新增資料之後的地址:%p", s) /* append新增資料,容量不夠,則另行開闢空間,切片地址發生變化 輸出: append新增資料之前的地址:0xc04200e2c0 append新增資料之後的地址:0xc04200a2d0 */ } func main() { /* copy(目的切片,原切片):切片拷貝 注意事項:目的切片要有足夠的空間,如果沒有空間(切片為空或者指向0x0),不能進行拷貝 若目的切片容量不足,只拷貝部分(目的切片長度的部分) 返回值為拷貝成功的切片數量 */ s := make([]int, 3) s[0] = 0 s[1] = 111 s[2] = 666 //var s1 []int = []int{5: 333} //n:=copy(s,s1) s1 := make([]int, 1, 2) n := copy(s1, s) fmt.Printf("原切片s的地址是:%p", s) fmt.Printf("\n拷貝之後的切片s1的地址是:%p,數量:%d", s1, n) fmt.Println(s1) }
補充說明:
陣列和slice之間有著緊密的聯絡。一個slice是一個輕量級的資料結構,提供了訪問陣列子序列(或者全部)元素的功能,而且slice的底層確實引用一個數組物件。一個slice由三個部分構成:指標、長度和容量。指標指向第一個slice元素對應的底層陣列元素的地址,要注意的是slice的第一個元素並不一定就是陣列的第一個元素。
切片並不是陣列或陣列指標,它通過內部指標和相關屬性引⽤陣列⽚段,以實現變⻓⽅案。
slice並不是真正意義上的動態陣列,而是一個引用型別。slice總是指向一個底層array,slice的宣告也可以像array一樣,只是不需要長度。