温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

go语言渐入佳境[13]-切片

发布时间:2020-07-29 21:41:13 阅读:195 作者:jonson_jackson 栏目:开发技术
GO开发者专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

切片

1、切片可以修改大小
2、切片的拷贝不是单纯值的拷贝,一个切片指向了一个数组

切片的声明

1234567
//切片的声明1  //nilvar slice1 []int  //切片的声明2var slice2 []int = make([]int,5)var slice3 []int = make([]int,5,7)numbers:= []int{1,2,3,4,5,6,7,8}

切片截取

12345678
numbers:= []int{1,2,3,4,5,6,7,8}//从下标1一直到下标4,但是不包括下标4numbers1 :=numbers[1:4]//从下标0一直到下标3,但是不包括下标3numbers2 :=numbers[:3]//从下标3一直到结束numbers3 :=numbers[3:]

切片截取例子

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
package mainimport "fmt"//1、切片可以修改大小//2、切片的拷贝不是单纯值的拷贝,一个切片指向了一个数组//切片的声明1var slice1 []int//切片的声明2var slice2 []int = make([]int,5)var slice3 []int = make([]int,5,7)func main(){	slice4 := make([]int,5)	slice5 := make([]int,5,7)	slice6 := make([]int,0)	fmt.Printf("len=%d,cap=%d,slice=%v\n",len(slice4),cap(slice4),slice4)	fmt.Printf("len=%d,cap=%d,slice=%v",len(slice5),cap(slice5),slice5)	if slice4 ==nil{		fmt.Printf("len=%d,cap=%d,slice=%v\n",len(slice4),cap(slice4),slice4)	}	//	slice6 := make([]int,0)不为nil	if slice6 !=nil{		fmt.Printf("len=%d,cap=%d,slice=%v\n",len(slice6),cap(slice6),slice6)	}	//var slice1 []int为nil	if slice1 ==nil{		fmt.Printf("len=%d,cap=%d,slice=%v\n",len(slice1),cap(slice1),slice1)	}	sliceTest()}//截取func sliceTest(){	numbers:= []int{1,2,3,4,5,6,7,8}	printSliceInfo(numbers)	numbers1 :=numbers[1:4]	printSliceInfo(numbers1)	numbers2 :=numbers[:3]	printSliceInfo(numbers2)	numbers3 :=numbers[3:]	printSliceInfo(numbers3)}//打印切片func printSliceInfo(x []int){	fmt.Printf("len=%d,cap=%d,slice=%v\n",len(x),cap(x),x)}

利用切片截取进行删除

1234567891011
//	切片删除//	删除第一个元素numbers = numbers[1:]   //	删除最后一个numbers = numbers[:len(numbers)-1]//删除中间一个元素a := int(len(numbers) / 2)numbers = append(numbers[:a], numbers[a+1:]...)

切片与数组的拷贝对比

数组的拷贝是副本拷贝。对于副本的改变不会影响到
切片的拷贝很特殊,切片的副本仍然指向了相同的数组。所以,对于副本的修改会影响到相同的数组。

下面的例子说明

12345678910111213141516171819202122
package mainimport "fmt"func main() {	//数组是值类型	a := [4]int{1, 2, 3, 4}	//切片是引用类型	b := []int{100, 200, 300}	c := a	d := b	c[1] = 200	d[0] = 1	fmt.Println("a=", a, "c=", c)	//c[1 200 3 4] a[1 2 3 4]	fmt.Println("b=", b, "d=", d)	//d[1 200 300]  b[1 200 300]}

append添加元素

12345678910111213
numbers := make([]int, 0, 20)//append一个元素numbers = append(numbers, 0)//append多个元素numbers = append(numbers, 1, 2, 3, 4, 5, 6, 7)//append添加切片s1 := []int{100, 200, 300, 400, 500, 600, 700}numbers = append(numbers, s1...) //[0 1 2 3 4 5 6 7 100 200 300 400 500 600 700]

copy

毫无疑问,创建新的目标切片就会有新的指向的数组。数组的copy是对于不同的数组的值的拷贝

12345
//创建目标切片numbers1 := make([]int, len(numbers), cap(numbers)*2)//	将numbers的元素拷贝到numbers1中count := copy(numbers1, numbers)

例子2

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
package mainimport "fmt"func main() {	fmt.Println("1、--------------")	//var numbers []int	numbers := make([]int, 0, 20)	//append一个元素	numbers = append(numbers, 0)	printSlice("numbers:", numbers) //[0]	//append多个元素	numbers = append(numbers, 1, 2, 3, 4, 5, 6, 7)	printSlice("numbers:", numbers) //[0 1 2 3 4 5 6 7]	//append添加切片	s1 := []int{100, 200, 300, 400, 500, 600, 700}	numbers = append(numbers, s1...) //[0 1 2 3 4 5 6 7 100 200 300 400 500 600 700]	printSlice("numbers:", numbers)	fmt.Println("2、--------------")	//	切片删除	//	删除第一个元素	numbers = numbers[1:]	printSlice("numbers:", numbers) //[ 1 2 3 4 5 6 7 100 200 300 400 500 600 700]	//	删除最后一个	numbers = numbers[:len(numbers)-1]	printSlice("numbers:", numbers) //[ 1 2 3 4 5 6 7 100 200 300 400 500 600]	//删除中间一个元素	a := int(len(numbers) / 2)	fmt.Println("中间下标:", a)	numbers = append(numbers[:a], numbers[a+1:]...)	printSlice("numbers:", numbers) //[1 2 3 4 5 6 100 200 300 400 500 600]	fmt.Println("3、--------------")	//创建目标切片	numbers1 := make([]int, len(numbers), cap(numbers)*2)	//	将numbers的元素拷贝到numbers1中	count := copy(numbers1, numbers)	fmt.Println("拷贝的个数:", count)	printSlice("numbers1:", numbers1)	//拷贝的两个切片是否有关联	numbers[0] = 99	numbers1[len(numbers1)-1] = 100	printSlice("numbers", numbers)	printSlice("numbers1", numbers1)}func printSlice(name string, x []int) {	fmt.Print(name, "\t")	fmt.Printf("地址:%p \t len=%d \t cap=%d \t value=%v \n", x, len(x), cap(x), x)}

疯狂切片原理

理解了下面代码到底输出什么,就理解了切片的原理。

12345678910111213141516
package mainimport "fmt"func f(s []string, level int) {        if level > 5 {               return        }        s = append(s, fmt.Sprint(level))        f(s, level+1)        fmt.Println("level:", level, "slice:", s)}func main() {        f(nil, 0)}

输出结果:

123456
level: 5 slice: [0 1 2 3 4 5]level: 4 slice: [0 1 2 3 4]level: 3 slice: [0 1 2 3]level: 2 slice: [0 1 2]level: 1 slice: [0 1]level: 0 slice: [0]

参考资料:
https://dave.cheney.net/2018/07/12/slices-from-the-ground-up

  • 本文链接: https://dreamerjonson.com/2018/11/20/golang-13-slice/

  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY 4.0 CN协议 许可协议。转载请注明出处!

go语言渐入佳境[13]-切片

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI

开发者交流群×