go語言中的切片事實上就是是乙個結構體,其執行時結構如下:
type slice struct
這一點非常重要,這也就意味著,將切片作為函式引數時,其傳遞機制與結構體傳遞機制一樣,都是值傳遞,也即傳遞的是原切片的拷貝。
另外乙個非常重要的點就是,切片結構體中的array是乙個指標,意味著array的值是底層陣列的位址,通過函式傳參後,這個值依然沒有改變。
因此可以看到,當把切片作為函式引數傳遞時,在函式中對切片進行某些修改操作,會影響到函式外的原始切片。
先看一段**:
func main()
fmt.printf("arr pointer: %p\n", &arr)
test(arr)
fmt.printf("arr: %v\n", arr)
}func test(data int)
問題:
請問上述**中arr pointer:
與data pointer:
的輸出是相同的嗎?
請問上述**中arr:
列印的結果是多少?也即函式中對切片的修改會不會影響到函式外的原切片?
答案:輸出中arr pointer:
與data pointer:
的值不相同,這很好理解,這是因為切片是值傳遞,傳遞給函式的時候,重新建立了乙個新的切片結構體,那麼二者的位址當然不一樣了。
列印的結果是arr: [100 2 3 4 5]
,也就證明了對切片的修改會影響到原切片。也正是這個原因導致很多人誤以為切片作為函式引數時是引用傳遞,其實這種理解是錯誤的。
func main()
fmt.printf("arr pointer: %p\n", &arr)
test(arr)
fmt.printf("arr: %v\n", arr)
}func test(data int)
那麼問題來了:
此時arr:
列印的結果是什麼?
最後,我想說的是,如果你確定編寫的函式需要將切片的修改影響到函式外的原始切片,那麼你的函式引數應該使用指標。
希望現在你可以清楚地回答下面的問題了
// **一
func main()
fmt.printf("arr pointer: %p\n", &arr)
test(&arr)
fmt.printf("arr: %v\n", arr)
}func test(data *int)
// **二
func main()
fmt.printf("arr pointer: %p\n", &arr)
test(&arr)
fmt.printf("arr: %v\n", arr)
}func test(data *int)
問題:
請問上述**中arr pointer:
與data pointer:
的輸出是相同的嗎?
請問上述**中arr:
列印的結果是多少?
附屬小問題:
var arr = int
fmt.printf("arr pointer: %p\n", arr)
fmt.printf("arr pointer: %p\n", &arr)
上面 Go 陣列 切片作為函式的引數。值傳遞 引用傳遞
demo.go 切片 陣列作為函式的形參 package main import fmt 值傳遞 改變形參的值,並不會改變實參的值。例如 陣列 結構體 陣列作為函式的引數,是值傳遞。修改形參不會改變實參的值。可以通過返回值來覆蓋 修改 實參的值 切片的資料存放在記憶體的堆區。陣列的資料 函式的區域性...
C 中陣列以及多維陣列作為函式引數時的一些問題
output1 ia,sizeof ia sizeof ia 0 今天在做 c primer 上的習題的時候,遇到了乙個小問題。原始函式如下 void output1 int a cout endl 陣列a為一維整型陣列,利用函式實現元素的依次輸出。但是編譯器在for int i a 處提示錯誤,i...
Redis作為快取時的一些使用經驗
redis作為nosql資料庫,經常用作快取,所以推薦將那些經常查詢的資料存入redis中方便下次快速獲取。但redis沒有像關係型資料庫那樣擁有結構化的查詢語言,如果快取了很多資料,想從中獲取滿足某些條件的資料時,該如何做呢?如果把這些海量資料從redis裡拿出來,逐個遍歷篩選出滿足條件的資料,這...