go語言切片作為函數參數的研究
阿新 • • 發佈:2019-02-02
修改 結果 main 長度 () port 切片slice cap lan
slice作為函數參數是值傳遞
golang中的切片slice底層通過數組實現,slice類似一個結構體,其中一個字段保存的是底層數組的地址,還有長度(len) 和 容量(cap)兩個字段。
結構體作為函數參數時是值拷貝,同理,實際上slice作為函數參數時也是值拷貝,在函數中對slice的修改是通過slice中保存的地址對底層數組進行修改,所以函數外的silce看起來被改變了。
當需要對slice做插入和刪除時,由於需要更改長度字段,值拷貝就不行了,需要傳slice本身在內存中的地址。
以刪除為例,說明這種情況。
不通過函數,直接刪除slice中的一個元素
package main import "fmt" func main() { si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Printf("%v len %d \n", si, len(si)) si = append(si[:3],si[4:]...) fmt.Printf("%v len %d \n", si, len(si)) } // ---------輸出結果------------------- [1 2 3 4 5 6 7 8 9] len 9 [1 2 3 5 6 7 8 9] len 8 // --------成功刪除了4 長度減1---------
通過函數,參數是slice變量
func main() { si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Printf("%v len %d \n", si, len(si)) test1(si) fmt.Printf("%v len %d \n", si, len(si)) } func test1(si []int) { si = append(si[:3], si[4:]...) } // -------------輸出結果------------------- [1 2 3 4 5 6 7 8 9] len 9 [1 2 3 5 6 7 8 9 9] len 9 // -----4雖然被刪除了,但是長度不變,最後面還多了個9,可見不是想要的結果
通過函數,參數是slice變量的地址
func main() { si := []int{1, 2, 3, 4, 5, 6, 7, 8, 9} fmt.Printf("%v len %d \n", si, len(si)) test(&si) fmt.Printf("%v len %d \n", si, len(si)) } func test(si *[]int) { (*si) = append((*si)[:3], (*si)[4:]...) } // ---------輸出結果------------------- [1 2 3 4 5 6 7 8 9] len 9 [1 2 3 5 6 7 8 9] len 8 // --------成功刪除了4 長度減1---------
go語言切片作為函數參數的研究