go内建容器-切片

1.基础定义

看到'切片'二字,满脸懵逼。切的啥?用的什么刀法切?得到的切片有什么特点?可以对切片进行什么操作?

先看怎么得到切片,也就是前两个问题。切片的底层是数组,所以切片切的是数组;切的时候采用半开半闭(取左舍右)的刀法,如同其他语言截取操作的规则

//s1、s2、s3就是我们要的切片
var array1 = [...]int{0,1,2,3,4,5,6}
var s1 []int
s1 = array1[0:3]
s2 := array1[3:]
s3 := array1[:4]

我们想得到一个东西不一定非得自己动手做,有很多途径可以得到一个成品,得到一个切片亦是如此

//声明一个切片并赋值
s1 := []int{0,1,2,3,4}
//创建一个长度和容量都是8的切片
s2 := make([]int,8)
//创建一个长度为10,容量为16的切片
s3 := make([]int,10,16)

2.切片的特性

得到切片后,我们就可以研究切片的特性了,来瞅瞅

在底层数组长度内,切片是向后延伸的,但不能向前延伸

一个长度为10的数组arr1,通过切它的2到4后得到一个切片s1,此时s1本身的长度为2(有两个值),s1的底层数组长度却为8(即s1的容量为8),虽然通过下标方式不能访问到s[2-7],但通过切s1的0到8得到的s2是一个切片长度和容量皆为8的切片

var array1 = [...]int{0,1,2,3,4,5,6,7,8,9}
s1 := array1[2:4]
//panic: runtime error: index out of range
//fmt.Println(s1[3])
s2 := s1[0:8]

用切片再切得到新切片时,用's3 := s1[2:]'(省略结束位置)的写法不能得到想要的结果,会得到容量(底层数组长度)正确但没有值的一个切片

//s2容量为4,但没有值,切片长度为0
var array1 = [...]int{0,1,2,3,4,5,6}
s1 := array1[1:3]
s3 := s1[2:]

3.切片操作

golang能操作切片内置函数(位于源码的src/builtin/builtin.go)有创建、打印、追加和复制,没有删除某个元素的操作,但通过追加可以实现删除(删除头、尾元素直接再切一次即可)

复制操作不会引起slice容量的改变,追加操作可能会引起容量变化

s1 := []int{0,1,2,3,4}
s2 := make([]int,8)
s3 := make([]int,10,16)
//复制操作,s2为sou,s1为dst,复制操作返回的值为为sou、dst长度的较小值
copy(s1,s2)
//追加操作,'s2[0:]...'表示s2从0开始到结束,可简写为's2...'
s3 = append(s3,s2[0:]...)
//用追加实现删除,后面的元素覆盖掉想要删除的元素
s2 = append(s2[:4],s2[5:]...)

测试代码

package main
import "fmt"
/*
从数组获得slice
*/
func declareSlice(){
	var array1 = [...]int{0,1,2,3,4,5,6}
	var s1 []int
	s1 = array1[0:3]
	s2 := array1[3:]
	s3 := array1[:4]
	printSlice(s1,s2,s3)
}
/*
slice特性
*/
func sliceTrait(){
	var array1 = [...]int{0,1,2,3,4,5,6,7,8,9}
	s1 := array1[2:4]
	//panic: runtime error: index out of range
	//fmt.Println(s1[3])
	s2 := s1[0:8]
	s3 := s1[0:]
	printSlice(s1,s2,s3)
}
/*
slice操作
*/
func sliceOperation()  {
	s1 := []int{0,1,2,3,4}
	s2 := make([]int,8,10)
	s3 := make([]int,5,32)
	s4 := make([]int,0)
	printSlice(s1,s2,s3)
	fmt.Println("Copying ...")
	n := copy(s2,s1)
	fmt.Println(n)
	copy(s3,s2)
	printSlice(s2,s3)
	fmt.Println("Appending  ...")
	s3 = append(s3,s2[0:]...)
	printSlice(s3)
	fmt.Println("Delete elements ...")
	s2 = append(s2[:4],s2[5:]...)
	printSlice(s2)
	fmt.Println("Test capacity ...")
	for m:=0;m<100;m++ {
		printSlice(s4)
		s4 = append(s4,m+1)
	}
}
func printSlice(s ... []int)  {
	for _,v := range s{
		fmt.Printf("value: %v  length: %d  capacity: %d \n", v,len(v),cap(v))
	}
}
func main() {
	declareSlice()
	sliceTrait()
	sliceOperation()
}
posted @ 2018-09-05 22:25  遥望1992  阅读(113)  评论(0编辑  收藏  举报