下面是一些Go書中的代碼片段。
func incr(s []int) {
s = append(s, 0)
for i := range s {
s[i]
}
}
func main() {
s1 :=[]int{1, 2}。
s2 := s1
s2 = append(s2, 3)
incr(s1)
incr(s2)
fmt.Print(s1, s2) // "[1, 2][2, 3, 4]"/span>。
}
我不明白為什么結果是"[1, 2][2, 3, 4]"
。基于https://golang.org/doc/effective_go#slices的兩個要點:
片斷持有對一個底層陣列的參考,如果你把一個片斷分配給另一個片斷,那么這兩個片斷都會參考同一個陣列
如果一個函式接受了一個片斷引數,那么它對片斷中的元素所做的改變將對呼叫者可見,這類似于傳遞一個指向底層陣列的指標
以下是我所想象的應該發生的情況:我認為應該是這樣的:
我認為應該是這樣的:
我認為應該是這樣的
一開始,s1和s2都有相同的底層陣列[1, 2] 。在向s2追加了3之后,底層陣列變成了[1, 2, 3]。但是s1仍然只看到[1, 2] 。在 。incr(s1)之后,s1被追加了0,并且所有項都被增加,結果s1變成了[2, 3, 1]。附加也改變了底層陣列,所以s2現在看到[2, 3, 1]在 。incr(s2)之后,s2被追加了0,并且所有的項被增加,結果s2變成了[3, 4, 2, 1]。增量也影響了底層陣列,所以現在s1看到了[3, 4, 2]所以列印出來的結果應該是 [3, 4, 2][3, 4, 2, 1] 我對圍棋中的分片的理解顯然有很大的錯誤。請告訴我哪里錯了。似乎我的推理與slice的行為是一致的。(我知道向一個容量不足的slice追加也會重新分配一個底層陣列,但不知道如何將其納入其中)。
uj5u.com熱心網友回復:
讓我們一步一步地分析這個程式:
s1 :=[]int{1, 2}. //s1 -> [1,2]/span> s2 := s1 //s1, s2 -> [1,2]下一個操作是:
s2 = append(s2, 3)如果底層陣列的容量不足,這可能分配一個新的支持陣列。在這種情況下,它將會這樣做,以給出:
s1 -> [1, 2] s2 -> [1,2, 3]然后
incr(s1)將向s1追加一個新的元素,增加數值,但是產生的片斷不會被分配給main中的s1,所以還是:s1 -> [1, 2] s2 -> [1,2, 3]
incr(s2)將做同樣的事情,但是這一次,后援陣列有能力容納附加的0,所以增量操作增加了值,但是新的片斷在main中從未被分配給s2。所以,s2仍然有3個元素:s1 -> [1, 2] s2 -> [2,3, 4]
s2的后援陣列中還有一個元素,但s2不包括該元素。轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/313484.html
標籤:
上一篇:在集成測驗中,MockMvc的作用是回傳nullPointerException。
下一篇:請求中缺少查詢引數
