golang的数组、切片和append一些小点

这几天刷题时,总是被切片和append坑了,重新看书后,发现是自己当时对他们认识不到位,重新补充下。

从代码分析:

var arr1  = [3]int{1,2,3}   //定义一个数组,需要在初始化时指定长度
var arr2  = arr1  //将一个数组赋值给另一个数组时,传递的是一份拷贝
arr2[1] = -2
fmt.Println(arr1,arr2) //[1 2 3] [1 -2 3]

// 不指定长度 则为切片
var sli1 = []int{1,2,3}
sli2  := sli1 // 切片是引用类型,切片包装的数组称为该切片的底层数组。
sli2[1] = -2
fmt.Println(sli1,sli2) //[1 -2 3] [1 -2 3]
总结:数组是值类型  切片是引用类型

那么当函数参数传切片的情况, 也一定是引用传递咯?其实不然

func main(){
   xyz := []int{1, 2, 3, 4, 5, 6, 7, 8, 9}
   rmLast(xyz)
   fmt.Printf("%v", xyz) //[1 2 3 4 5 6 7 8 9]

   rmLast1(&xyz)
   fmt.Printf("%v", xyz) //[1 2 3 4 5 6 7 8]
}

func rmLast(a []int) { //slice作为函数参数传入函数时,实际上也是拷贝了一份slice
   a = a[:len(a)-1]
}

func rmLast1(a *[]int) {
   *a = (*a)[:len(*a)-1]
}

再看append,通常使用append如下:

sli4 := append(sli3,6,7)

我理所当然的认为,既然append的返回值赋给了新元素,当然不会改变sli3的值,其实不然,准确的说不一定,看两段代码:

//append是一个内置函数,用来在指定的slice后面添加1个或多个元素,并且返回一个新的slice。
var arr3 [5]int  = [5]int{1,2,3,4,5}
sli3 := arr3[:2] // slice3仍然指向arr3
//如果slice的底层数组有足够的空间,那么append函数被调用以后,并不会为新返回的slice分配一个新的数组,而是使用原来的数组。
//这样的话,当改动了新返回的slice以后,原数组也会发生相应的改变。
sli3 = append(sli3,6,7)
fmt.Println(arr3,sli3)  // [1 2 6 7 5] [1 2 6 7]

var arr4 [5]int  = [5]int{1,2,3,4,5}
sli4 := arr3[:2] // slice3仍然指向arr3
//如果原数组中没有足够的空间的情况下,就会分配一个新的数组,那么再对slice做的任何改变,都与原数组没有关系了
sli4 = append(sli4,6,7,8,9,10)
fmt.Println(arr4,sli4)  // [1 2 3 4 5] [1 2 6 7 8 9 10]
总结:如果append以后的元素个数已经超过了切片的容量(即切片的底层数组的容量),就会分配一个新的slice
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值