GoLang学习笔记(二十二)切片的append()和copy()

首先新建一个切片:

var numbers []int

然后通过append()函数来为numbers添加一个元素0:

numbers = append(numbers, 0)

也可以通过append()函数来为numbers添加多个元素:

numbers = append(numbers, 1, 2, 3, 4, 5, 6, 7)

还可以为numbers做切片的合并:

s1 := []int{11, 12, 13, 14, 15, 16, 17}
numbers = append(numbers, s1...)

在切片的最前面添加元素:

numbers = append([]int{99}, numbers...)

利用多个append()函数组合起来操作,实现在切片中间添加元素

func testAppend3(i, x int, a []int) []int {
	//如果添加得位置超过a得长度,则直接添加在最后
	if i <= len(a) {
		a = append(a[:i], append([]int{x}, a[i:]...)...)
		return a
	} else {
		a = append(a, x)
        return a
	}
}

func main() {
	numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
	numbers = testAppend3(12, 99, numbers)
	printSlice("最后得结果为:", numbers)
}

也可以用append()函数来删除切片numbers中的某一个元素:

//删除第一个元素
numbers = numbers[1:]
//删除最后一个元素
numbers = numbers[:len(numbers)-1]
//删除中间一个元素
a := len(numbers) / 2
numbers = append(numbers[:a], numbers[a+1:]...)

通过copy()函数来拷贝切片,先建两个切片:

numbers1 := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
numbers2 := make([]int, len(numbers1), cap(numbers1)*2)

使用copy()来将number1拷贝给numbers2:

copy(numbers2, numbers1)

拷贝后的两个切片是没有关联的,修改numbers1的元素,不会影响到numbers2。

也可以通过copy函数来删除开头的元素

//删除开头1个个元素
numbers = numbers[:copy(numbers,numbers[1:])]
//删除开头第N个元素
numbers = numbers[:copy(numbers,numbers[N:])]
//删除中间一个元素
a := len(numbers) / 2
numbers = numbers[:a+copy(numbers[a:],numbers[a+1:])]

利用copy函数与append函数组合,在指定的切片下标位置,添加元素,避免了组合使用append函数添加中间创建临时切片

func testAppend4(i, x int, a []int) []int {
	if i <= len(a) {
		a = append(a,0)
		copy(a[i+1:],a[i:])
		a[i] = x
		return a
	} else {
		a = append(a, x)
		return a
	}
}
func main() {
	numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
	numbers = testAppend4(1, 99, numbers)
	printSlice("最后得结果为:", numbers)
}

给大家一个去掉字符数组里空格元素的例子,下面的代码,在每一次b增加一个元素时,就会增加一个新的切片来接收扩容后的b,这样就会造成每次都会有内存新的分配。

func testAppendCap1(s []byte) []byte{
	var b []byte
	for _,v := range s{
		if v != ' '{
			b = append(b, v)
		}
	}
	return b
}

为了避免上面的情况发生,优化代码,当b被创建时,就利用了golang空切片的特性,创建成len为0,cap则和切片s一致。这样在后面的代码执行时,降低了内存分配的次数和每次分配内存的大小。

func testAppendCap2(s []byte) []byte{
	b := s[:0]
	for _,v := range s{
		if v != ' '{
			b = append(b, v)
		}
	}
	return b
}

PS:使用var创建切片,在append方法时,内存地址在不停的变化,使用make创建切片时,可以适当的加大cap参数,可以避免内存地址的不断创建和回收,由此可以发现,make创建并初始化切片比var要更好。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值