GoLang中Slice的append

package main

import "fmt"

func main() {
	s := []int{5}
	s = append(s, 8)
	s = append(s, 9)
	x := append(s, 11)
	y := append(s, 12)
	fmt.Println(s, x, y)
}

以上代码会输出结果

[5 8 9] [5 8 9 12] [5 8 9 12]

结果中 x 被 y 覆盖了

原因是 slice 的容量增长

func main() {
	s := []int{5}
	fmt.Println("capacity:", cap(s))
	s = append(s, 8)
	fmt.Println("capacity:", cap(s))
	s = append(s, 9)
	fmt.Println("capacity:", cap(s))

	x := append(s, 11)
	fmt.Println("x s capacity:", cap(s))
	y := append(s, 12)
	fmt.Println("y s capacity:", cap(s))
	fmt.Println(s, x, y)
}

逐一打印总容量后发现s的容量增长记录

capacity: 1
capacity: 2
capacity: 4
x s capacity: 4
y s capacity: 4

s 当增长到4时因没有新元素计入不再增长
而 x 则是在原本 s 索引 [3] 的地方修改为了 11
y 则是在原本 s 索引 [3] 的地方修改为了 12
但为什么 12 会把 11 覆盖了呢

执行以下代码后发现,三个切片里的各元素的地址一致

func main() {
	s := []int{5}
	s = append(s, 8)
	s = append(s, 9)
	fmt.Println(&s[0], &s[1], &s[2])
	x := append(s, 11)
	fmt.Println(&x[0], &x[1], &x[2], &x[3])
	y := append(s, 12)
	fmt.Println(&y[0], &y[1], &y[2], &y[3])
}

输出结果后

0xc0000a8140 0xc0000a8148 0xc0000a8150
0xc0000a8140 0xc0000a8148 0xc0000a8150 0xc0000a8158
0xc0000a8140 0xc0000a8148 0xc0000a8150 0xc0000a8158

查看 append 源码

// The append built-in function appends elements to the end of a slice. If
// it has sufficient capacity, the destination is resliced to accommodate the
// new elements. If it does not, a new underlying array will be allocated.
// Append returns the updated slice. It is therefore necessary to store the
// result of append, often in the variable holding the slice itself:
//	slice = append(slice, elem1, elem2)
//	slice = append(slice, anotherSlice...)
// As a special case, it is legal to append a string to a byte slice, like this:
//	slice = append([]byte("hello "), "world"...)
func append(slice []Type, elems ...Type) []Type

源码里表示,“如果原切片拥有足够的容量时,目标会重新切片并容纳新元素”。
也就是说返回的还是 s 本身的副本(指向地址都是一样的),而不是新的切片。
只有当 cap 超出最大时才会返回一个新的切片(指向地址都不一样)。

func main() {
	s := []int{5}
	s = append(s, 8)
	s = append(s, 9)
	x := append(s, 11)
	fmt.Println(&x[0], &x[1], &x[2], &x[3])
	fmt.Println("x capacity:", cap(x))
	y := append(s, 12, 13)
	fmt.Println(&y[0], &y[1], &y[2], &y[3], &y[4])
	fmt.Println("y capacity:", cap(y))
}

输出结果

0xc00000e3e0 0xc00000e3e8 0xc00000e3f0 0xc00000e3f8
x capacity: 4
0xc000010240 0xc000010248 0xc000010250 0xc000010258 0xc000010260
y capacity: 8
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值