数组与切片

go中的切片(Slice)相对于其它语言来说是一个特色

切片,顾名思义,切的是数组,成就的是数组中的一个片段

切片是一个具有相同元素的一个可自然增长的序列。非常灵活,可支持扩容

切片是一个引用类型,内部结构包含地址,长度和容量,可以快速的操作一块数据集合

举个例子,有一个数组a := [8]int{0, 1, 2, 3, 4, 5, ,6, 7},切片s1 := a[:5]

切片s1 := a[:5],因为数组地址是从0开始,相当于对于切片的解读,左闭右开,左包含,右不包含

切片s2 := a[3:6],示意图如下

切片表达式

完整的切片表达式

a[low : hign : max]

high的上限边界是切片的容量cap(a),切片的索引必须满足0 <= low <= hign <= len(a)

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	s := a[1:3]  // s := a[low:high]
	fmt.Printf("s:%v len(s):%v cap(s):%v\n", s, len(s), cap(s))
	s2 := s[3:4]  // 索引的上限是cap(s)而不是len(s)
	fmt.Printf("s2:%v len(s2):%v cap(s2):%v\n", s2, len(s2), cap(s2))
}

 切片之间不能直接比较,不能用 == 操作符判断两个切片是否含有全部相等元素,切片唯一合法的比较操作时和nil比较。

一个nil值的切片并没有底层数组,一个nil值的切片的长度和容量都是0。但是我们不能说一个长度和容量都是0的切片一定是nil

例如下面的示例

var s1 []int         //len(s1)=0;cap(s1)=0;s1==nil
s2 := []int{}        //len(s2)=0;cap(s2)=0;s2!=nil
s3 := make([]int, 0) //len(s3)=0;cap(s3)=0;s3!=nil

所以如果想要判断一个切片是否为空,只能用len(s) == 0来判断,不能用s == nil判断 

index,value是切片的两个元素

即遍历这个切片可以使用遍历索引

func main() {
	s := []int{1, 3, 5}

	for i := 0; i < len(s); i++ {
		fmt.Println(i, s[i])
	}

	for index, value := range s {
		fmt.Println(index, value)
	}
}

当然,for索引也是可以的

 切片扩容

append()可以为切片动态的添加元素

func main(){
	var s []int
	s = append(s, 1)        // [1]
	s = append(s, 2, 3, 4)  // [1 2 3 4]
	s2 := []int{5, 6, 7}  
	s = append(s, s2...)    // [1 2 3 4 5 6 7]
}

可以将一个切片后面添加上元素,也可以为一个切片后面添加上一个切片。

当然,切片的扩容也是通过append()

 

func main() {
	//append()添加元素和切片扩容
	var numSlice []int
	for i := 0; i < 10; i++ {
		numSlice = append(numSlice, i)
		fmt.Printf("%v  len:%d  cap:%d  ptr:%p\n", numSlice, len(numSlice), cap(numSlice), numSlice)
	}
}

append()函数就像一个胶带把切片中的各个元素串联起来,专心为切片结构服务

修改元素的值需要首先知道该元素的地址,切片结构就是引用类型,即凭着接片上的index就可以得到所储存的元素,直接修改值即可

func main() {
	a := []int{1, 2, 3, 4, 5}
	b := a
	fmt.Println(a) //[1 2 3 4 5]
	fmt.Println(b) //[1 2 3 4 5]
	b[0] = 1000
	fmt.Println(a) //[1000 2 3 4 5]
	fmt.Println(b) //[1000 2 3 4 5]
}

copy()切片的使用格式为:

copy(destSlice, srcSlice []T)
func main() {
	// copy()复制切片
	a := []int{1, 2, 3, 4, 5}
	c := make([]int, 5, 5)
	copy(c, a)     //使用copy()函数将切片a中的元素复制到切片c
	fmt.Println(a) //[1 2 3 4 5]
	fmt.Println(c) //[1 2 3 4 5]
	c[0] = 1000
	fmt.Println(a) //[1 2 3 4 5]
	fmt.Println(c) //[1000 2 3 4 5]

切片是引用类型,可以直接对值进行修改,Go语言中,一般前面为主,后面是对该元素的定的类型,可延展为在copy(a,c)中,a是主,将c的值赋给a

切片中删除元素比较难,Go语言中没有专门的函数来删除切片中的元素,所以只能根绝切片的特性来删除元素

func main() {
	// 从切片中删除元素
	a := []int{30, 31, 32, 33, 34, 35, 36, 37}
	// 要删除索引为2的元素
	a = append(a[:2], a[3:]...)
	fmt.Println(a) //[30 31 33 34 35 36 37]
}

可以理解为,把切片分成段,然后用append()函数,将除了要删除的元素的下标,其它的元素串联起来其格式为 

删除索引为index的元素:

a = append(a[:index],a[index+1]...)

左包含,右不包含

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值