slice的用法以及和数组的区别

slice是go的一个语言特性,其实有点类似于cpp的vector,可变长度,可以扩展空间。今天详细看了下,做下总结。
slice本质上是一个区间,原型是[]T,大致的实现是这样的:

type slice struct {
    first *T
    len int
    cap int
}

可以看到的是是一个指向数组的指针,那么在修改slice的时候会改变数组的值。
和数组的用法差别不是太大。

  1. 基于数组的创建:
var myArrary [3]int = [3]int{1,2,3}
var mySlice []int = myArray[:2] //[first:last]方式,不足时补0
  1. 直接创建:
mySlice = make([]int, 5)//创建了长度为5初值为0的切片
mySlice = make([]int, 5, 10)//创建了长度为5,容量为10的切片
  1. 函数 :
    len() 返回元素的个数
    cap()返回容器大小
    append()新增元素
mySlice = append(mySlice, 1, 2, 3) //后者的参数类型其实是不定参数
mySlice2 = []int{7, 8, 9}
mySlice = append(mySlice, mySlice2...) 加入...表示打散后传入
  1. copy()深复制slice
slice1 := []int{1, 2, 3, 4, 5}
slice2 := []int{1, 2, 3}
copy(slice2, slice1)//copy slice的前3个元素到slice2
slice2 = slice1 //会复制一份引用给slice2
  1. 和数组区别
func arrayModify(array [5]int) {
    newArray := array
    newArray[0] = 88
}
func sliceModify(slice []int) {
    newSlice := slice
    newSlice[0] = 88
}
func main() {
    array := [5]int{1, 2, 3, 4, 5}
    slice := []int{1, 2, 3, 4, 5}
    arrayModify(array)
    sliceModify(slice)
    fmt.Println(array)
    fmt.Println(slice)
}
// [1 2 3 4 5]
// [88 2 3 4 5]

可以看到的是数组传的是值,不会改变元素的值,这一点和c/cpp不同,而虽然slice也是值语义,但是其本身是指针类型的,所以会改变值,但不意味着slice传引用,这一点需要注意。后面会详细讲值语义带来的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值