slice和数组使用上的坑

slice和数组区别
  • 数组长度不可变,slice是长度可变的
  • 数组的内存分配固定大小,slice底层引用的其实就是数组
  • 切片是应用类型,在作为值传递时,效率高于数组
demo1
func main() {
	var sl []int
	sl = append(sl, 9, 7, 5)
	f(sl)
	fmt.Println(sl) //[9 7 5]
}

// 函数参数传递,函数参数传递是值传递
func f(sl []int) {
	// 这里首先发生了扩容,sl不再是指向slice,而是指向slice的副本
	for i := 0; i < 3; i++ {
		sl = append(sl, i)
	}

	//这里修改的是slice的副本,而不是slice
	for i := 0; i < 3; i++ {
		sl[i] = sl[i] + 2
	}

	fmt.Println(sl) // [11 9 7 0 1 2]
}
	
demo2
func main() {
	var sl []int
	sl = append(sl, 9, 7, 5)
	f(sl)
	fmt.Println(sl) //[11 9 7]
}

// 函数参数传递,函数参数传递是值传递
func f(sl []int) {
	//这里修改的是slice底层的数组,所以会导致sl的值发生变化
	// sl[0] = sl[0] + 2
	for i := 0; i < 3; i++ {
		sl[i] = sl[i] + 2
	}

	// 这里首先发生了扩容,在sl的基础上扩容了3个元素
	for i := 0; i < 3; i++ {
		sl = append(sl, i)
	}

	fmt.Println(sl) // [11 9 7 0 1 2]
}

demo3
func main() {
	var sl []int
	sl = append(sl, 9, 7, 5)
	f(sl)
	fmt.Println(sl) //[11 7 5]
}

// 函数参数传递,函数参数传递是值传递
func f(sl []int) {
	for i := 0; i < 3; i++ {
		sl[i] = sl[i] + 2 // 第一轮循环时修改了sl底层数组,sl[0]发生改变
		sl = append(sl, i) // 第一轮循环发生长度的变化,底层数组发生改变,后续不再修改sl,而是sl的副本
	}

	fmt.Println(sl) // [11 9 7 0 1 2]
}	
demo4
//通过return或者指针方式可以改变原来数组
func myAppend(sl []int) []int {
	// 这里 sl 虽然改变了,但并不会影响外层函数的 sl
	sl = append(sl, 100)
	return sl
}

func myAppendPtr(sl *[]int) {
	// 会改变外层 s 本身
	*sl = append(*sl, 100)
	return
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值