go 切片對數組的修改,切片的擴容


go中數組是值拷貝,

切片是對上層數組的表示,應該是使用的是數組地址,修改時是直接對原來的數組進行修改

片作為函數參數依舊如此

slice或者array作為函數參數傳遞的時候,本質是傳值而不是傳引用。傳值的過程復制一個新的切片,這個切片也指向原始變量的底層數組。

 

 

var array [5]int=[5]int{1,2,3,4,5}//可以簡化為array:=[5]int{1,2,3,4,5} 初學所以沒有簡化
	var slice[]int =array[1:3]

	fmt.Println(array)
	for i:=range slice{
		slice[i]+=100
	}
	fmt.Println(array)

	fmt.Println(slice)

  輸出

 

 

 說明切片是對數組的引用,更改切片時原數組會發生變化。

因為切片保留對數組的引用,切片在,數組內存不能回收,所以數組大而使用切片為其中一小部分時應該使用切片的拷貝方式。

 

var array [7]int=[7]int{1,2,3,4,5,6,7}
	var slice[]int =array[:3]
	sliceneed:=make([]int,len(slice))
	copy(sliceneed,slice)
	fmt.Println(sliceneed)

  結果

 

 

 

追加一個一個切片到另一個后面可以用append方式帶...

var array [5]int=[5]int{1,2,3,4,5}//可以簡化為array:=[5]int{1,2,3,4,5} 初學所以沒有簡化
	var slice[]int =array[1:3]
	fruits := []int{6,7}
	slice =append(slice,fruits...)

  

 

9.24增加切片擴容機制

部分源碼

// src/runtime/slice.go
func growslice(et *_type, old slice, cap int) slice {
// ...省略部分
    newcap := old.cap
    doublecap := newcap + newcap
    if cap > doublecap {//大於兩倍使用多的容量
        newcap = cap
    } else {
        if old.len < 1024 {//小於1024 使用兩倍
            newcap = doublecap
        } else {//否則依次擴大25%,直到復合容量
            // Check 0 < newcap to detect overflow
            // and prevent an infinite loop.
            for 0 < newcap && newcap < cap {
                newcap += newcap / 4
            }
            // Set newcap to the requested cap when
            // the newcap calculation overflowed.
            if newcap <= 0 {
                newcap = cap
            }
        }
    }
// ...省略部分
}

  

  • 當需要的容量超過原切片容量的兩倍時,會使用需要的容量作為新容量。
  • 當原切片長度小於1024時,新切片的容量會直接翻倍。而當原切片的容量大於等於1024時,會反復地增加25%,直到新容量超過所需要的容量。
  為了避免因為切片是否發生擴容的問題導致bug,最好的處理辦法還是在必要時使用  copy 來復制數據,保證得到一個新的切片,
  避免后續操作帶來預料之外的副作用。

參考鏈接:https://www.jianshu.com/p/54be5b08a21c

 
 
預測輸出
         var x =[]int{1,2,3}
	var y = x[:2]

	y = append(y,50)
	y = append(y,60)
	
	fmt.Println(x)
	y[0] = 20
	fmt.Println(y)

 

 

 結果,y初始和x引用相同底層數組,切容量未超出,所以第一個append正常修改,

 第二個append時超出容量,擴容使用新的底層數組,之后再修改y是更改自己的數據。

 
 
 
 
今天寫leetcode遇到個奇怪的問題。
一個切片append另外一個,是非拷貝方式的,修改第二個切片值會影響結果
test:=[]int{1,2,3} two:=[]int{4,5,6} two[0] = 9 test = append(test,two...) fmt.Println(test[:len(test)])

 

 修改第二個會影響結果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM