如果想增加切片的容量,我們必須創(chuàng)建一個新的更大的切片并把原分片的內(nèi)容都拷貝過來。下面的代碼描述了從拷貝切片的 copy 函數(shù)和向切片追加新元素的 append 函數(shù)。
示例 7.12 copy_append_slice.go
package main
import "fmt"
func main() {
sl_from := []int{1, 2, 3}
sl_to := make([]int, 10)
n := copy(sl_to, sl_from)
fmt.Println(sl_to)
fmt.Printf("Copied %d elements\n", n) // n == 3
sl3 := []int{1, 2, 3}
sl3 = append(sl3, 4, 5, 6)
fmt.Println(sl3)
}
func append(s[]T, x ...T) []T
其中 append 方法將 0 個或多個具有相同類型 s 的元素追加到切片后面并且返回新的切片;追加的元素必須和原切片的元素同類型。如果 s 的容量不足以存儲新增元素,append 會分配新的切片來保證已有切片元素和新增元素的存儲。因此,返回的切片可能已經(jīng)指向一個不同的相關(guān)數(shù)組了。append 方法總是返回成功,除非系統(tǒng)內(nèi)存耗盡了。
如果你想將切片 y 追加到切片 x 后面,只要將第二個參數(shù)擴(kuò)展成一個列表即可:x = append(x, y...)
。
注意: append 在大多數(shù)情況下很好用,但是如果你想完全掌控整個追加過程,你可以實(shí)現(xiàn)一個這樣的 AppendByte 方法:
func AppendByte(slice []byte, data ...byte) []byte {
m := len(slice)
n := m + len(data)
if n > cap(slice) { // if necessary, reallocate
// allocate double what's needed, for future growth.
newSlice := make([]byte, (n+1)*2)
copy(newSlice, slice)
slice = newSlice
}
slice = slice[0:n]
copy(slice[m:n], data)
return slice
}
func copy(dst, src []T) int
copy 方法將類型為 T 的切片從源地址 src 拷貝到目標(biāo)地址 dst,覆蓋 dst 的相關(guān)元素,并且返回拷貝的元素個數(shù)。源地址和目標(biāo)地址可能會有重疊??截悅€數(shù)是 src 和 dst 的長度最小值。如果 src 是字符串那么元素類型就是 byte。如果你還想繼續(xù)使用 src,在拷貝結(jié)束后執(zhí)行 src = dst
。
練習(xí) 7.9
給定 slice s[]int
和一個 int 類型的因子,擴(kuò)展 s 使其長度為 len(s) * factor
。
練習(xí) 7.10
用順序函數(shù)過濾容器:s 是前 10 個整型的切片。構(gòu)造一個函數(shù) Filter,第一個參數(shù)是 s,第二個參數(shù)是一個 fn func(int) bool
,返回滿足函數(shù) fn 的元素切片。通過 fn 測試方法測試當(dāng)整型值是偶數(shù)時的情況。
練習(xí) 7.11
寫一個函數(shù) InsertStringSlice 將切片插入到另一個切片的指定位置。
練習(xí) 7.12
寫一個函數(shù) RemoveStringSlice 將從 start 到 end 索引的元素從切片 中移除。