golang 的slice是一個指向底層的數(shù)組的指針結(jié)構(gòu)體。
這個結(jié)構(gòu)體有三個屬性,1.指向數(shù)組指針,2.len: slice中元素的數(shù)量 3.cap:slice占用內(nèi)存數(shù)量。
只有深刻理解這三個屬性才能在使用slice中不至于犯錯。 (推薦學習:go)
正確理解變量和共享
多個slice之間可以共享底層的數(shù)據(jù),并且引用的數(shù)組部分區(qū)間可能重疊
以上是golang 圣經(jīng)中的一句話。深刻理解這句話對于日程編程非常有意義。
什么時候共享數(shù)據(jù)會被其他變量修改
func f1() { a1 := []int{1,2,3,4,5,6} a2 := a1 a3 := a1[1:3] a1[1] = 999 fmt.Println("a1=",a1,"a2=",a2,"a3=",a3) }
運行結(jié)果
a1= [1 999 3 4 5 6] a2= [1 999 3 4 5 6] a3= [999 3] Process finished with exit code 0
我們清楚的看到了數(shù)據(jù)共享,此時修改了a1 ,兩位兩個變量都被修改
什么時候不會修改
func f2() { a1 := []int{1,2,3,4,5,6} a2 := a1 a3 := a1[1:3] a2 = append(a2,888) a1[1] = 999 fmt.Println("a1=",a1,"a2=",a2,"a3=",a3) }
運行結(jié)果
a1= [1 999 3 4 5 6] a2= [1 2 3 4 5 6 888] a3= [999 3] Process finished with exit code 0
可以雖然a1被修改,a2并沒有修改。我們知道append函數(shù)會面臨內(nèi)存的重新分配。所以等a2進行append的時候,會重新申請內(nèi)存空間,將原有數(shù)組拷貝然后增加如新值。也就是當append操作的時候,此時a2 不在和a1 共享內(nèi)存了。
在對slice復制的時候,如果面臨多個變量同時指向一個數(shù)組的時候,一定要考慮到數(shù)據(jù)的共享和內(nèi)存的重新分配。