Go语言攻略:如何使用切片

      Go语言中,函数传参都是值传递。如果我们希望传递一个数组,并且能够在函数中进行修改,那该如何做?使用指针当然可以,但作为21世纪的C语言,Go使用切片这种方式来实现这样的功能。

写一个切片

func main(){
	arr := [...]int{0,1,2,3,4,5,6,7}
	s := arr[2:6]
	fmt.Println(s)
}

学过python的同学都知道,arr[2.6]表示的是从数组的第二个元素到第六个元素之前进行切片。输出为:[2 3 4 5]。

除此之外,arr[:6]表示从头到第六个元素之前元素的视图,arr[2:]表示从二开始切到最后一个,arr[:]则表示全部内容的视图。而Go中并不支持诸如[:-2]的视图,这在python中是具有意义的。

修改切片

如果对切片进行修改,数组会改变吗?

func main(){
	arr := [...]int{0,1,2,3,4,5,6,7}
	s := arr[2:6]
	s[1] =10
	fmt.Println(s,arr)
}

在这段代码中,我们对切片的第一个元素进行了修改,结果输出为[2 10 4 5] [0 1 2 10 4 5 6 7]。由此可见,对切片进行修改,不仅修改了切片的内容,也修改了原始的数组。

Slice本身是没有数据的,是对底层的视图。

对切片切片

func main(){
	arr := [...]int{0,1,2,3,4,5,6,7}
	s := arr[2:6]
	s1 := s[:4]
	s2 := s[2:]
	fmt.Println(s,s1,s2)
}

执行这段代码,结果为[2 3 4 5] [2 3 4] [4 5]。可见我们可以对切片进行继续切片。

但如果新切片范围超过了原来的切片,会发生什么?

func main(){
	arr := [...]int{0,1,2,3,4,5,6,7}
	s := arr[2:6]
	s1 := s[3:5]
	fmt.Println(s,s1)
}

根据结果[2 3 4 5] [5 6], 可推至新的slice可以看得到数组右边没有被切的部分。

在slice的底层实现中,切片的长度可由len()得,而切片始到数组结尾可以用cap()获得。只要不大于cap()返回的值,切片就都可以对数组产生视图。也就是说Slice可以进行向后扩展(下标取值不能超越s[len(s)],视图不可以超越cap(s))

向slice添加元素

如下列程序,我们对slice进行扩充:

func main(){
	arr := [...]int{0,1,2,3,4,5,6,7}
	s := arr[2]:6
	s1 := s[3:5]
	s2:= append(s1,10)
	s3 := append(s2,11)
	s4:= append(s3,12)
	fmt.Println(s,s1,s2,s3,s4)
}

其结果为:[2 3 4 5] [5 6][5 6 10] [5 6 10 11] [5 6 10 11 12]。

可见,可以使用append对切片进行扩展。但,当添加元素超过cap(),系统会重新分配更大的底层数组。由于gc的存在,原数组如果不用可能会被释放掉,而扩展的切片也不再是原数组的视图。

创建一个Slice

可用以下代码创建一个切片:

	var s []int

	for i :=  0; i<100; i++{
		s = append(s,2*i+1)
	}
	fmt.Println(s)

也可以使用如下方法创建:

func main() {
	s1 := []int{2, 4, 6, 8}
	s2 := make([]int, 18)
	fmt.Println(s1, s2)
}

可以直接初始化切片的值,也可以使用make来按指定长度创建slice。

切片的拷贝

可以使用copy()函数对slice进行拷贝

func main() {
	s1 := []int{2, 4, 6, 8}
	s2 := make([]int, 18)
	copy(s2,s1)
	fmt.Println(s1, s2)
}

结果为[2 4 6 8] [2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0]

切片删除值

如何s2中删除第三个元素?

func main() {
	s1 := []int{2, 4, 6, 8}
	s2 := make([]int, 18)
	copy(s2,s1)
	s2 = append(s2[:3],s2[4:]...)
	fmt.Println(s1, s2)
}

同样的,截掉头尾元素,可以使用诸如下面的方法

s2 =  s2[1:]

s2 = s2[:len(s2-1)]

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值