Files
the-way-to-go_ZH_CN/eBook/07.5.md
2013-11-23 15:13:25 +08:00

2.8 KiB
Raw Blame History

#7.5 拷贝与追加slice 如果想增加slice的容量我们必须创建一个新的更大的slice并把原分片的内容都拷贝过来。下面的代码描述了从拷贝slice的copy方法和向slice追加新元素的append方法。

示例 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的元素追加到slice后面并且返回新的slice追加的元素必须和原slice的元素同类型。如果s的容量不足以存储新增元素append会分配新的slice来保证已有slice元素和新增元素的存储。因此返回的slice可能已经指向一个不同的相关数组了。append方法总是返回成功除非系统内存耗尽了。

如果你想将slice y追加到slice x后面只要将第二个参数扩展成一个列表即可 x = append(x, y...)

注意 append在大多数情况下很好用但是如果你想完全掌控整个追加过程你可以实现一个这样的AppendByte方法

func AppendByte(slice []byte, data ...byte[]) []byte {
	m := len(slice)
	n := m + len(data)
	if n > cap(slice) { // if necessary, reallocate
		// allocate doublke 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的slice从源地址src拷贝到目标地址dst覆盖dst的相关元素并且返回拷贝的元素个数。源地址和目标地址可能会有重叠。拷贝个数是src和dst的长度最小值。如果src是字符串那么元素类型就是byte。如果你还想继续使用src在拷贝技术后执行src =dst。

练习 7.9 magnify_slice.go: 给定slice s[]int和一个int类型的因子扩展s使其长度为len(s) * factor。

练习 7.10filter_slice.go 用顺序函数过滤容器s是前10个整形的slice。构造一个函数Filter第一个参数是s第二个参数是一个fn func(int) bool返回满足函数fn的元素slice。通过fn测试方法测试当整型值是偶数时的情况。

练习 7.11insert_slice.go写一个函数InsertStringSlice将slice插入到另一个slice的指定位置。

练习 7.12remove_slice.go写一个函数RemoveStringSlice将从start到end索引的元素从slice中移除。

##链接