golang中slice的注意事项

lijingtian · · 626 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

1. slice本质上是基于数组的一种数据结构(struct),是数组的一种透视。 2. slice的数据结构为: ```go type slice struct { array unsafe.Pointer len int cap int } ``` 请注意, array是一个指针类型。 3. slice作为数组的一部分透视来使用: ```go testArr := [5]int{0, 1, 2, 3, 4} sliceFromArr := testArr[1:3] fmt.Println(sliceFromArr) // [1, 2] sliceFromArr[0] = 11 fmt.Println(testArr) //[0 11 2 3 4] fmt.Printf("len: %d, cap: %d, data:%+v \n",len(sliceFromArr), cap(sliceFromArr), sliceFromArr) //len: 2, cap: 4, data:[11 2] //修改slice同时会修改array,因为slice中有array的指针 sliceFromArr = append(sliceFromArr, 33, 44) fmt.Println(testArr) //[0 11 2 33 44] fmt.Printf("len: %d, cap:%d, data:%+v \n", len(sliceFromArr), cap(sliceFromArr), sliceFromArr) //len: 4, cap:4, data:[11 2 33 44] //当len小于透视的数组的length时,对slice的修改都会同时修改它透视的数组 sliceFromArr = append(sliceFromArr, 55) fmt.Println(testArr) //[0 11 2 33 44] fmt.Printf("len: %d, cap: %d, data:%+v \n", len(sliceFromArr), cap(sliceFromArr), sliceFromArr) //len: 5, cap: 8, data:[11 2 33 44 55] //append()当len大于cap时,会重新开辟为原来slice的cap两倍的内存空间,并把slice拷贝到新开辟的空间中。 //所以原来的数组显示的依旧是原来的内存地址中的数据,而现在的slice已经存储来一个新开辟的8个int的空间中, //对slice的修改不会改动原来的数组。 ``` 4. slice单独定义,并作为参数传递给函数: ```go func setSlice(testSlice []int){ testSlice[0] = 10 testSlice[1] = 11 } func setSliceByAppend(testSlice []int){ testSlice = append(testSlice, 22) } func setSliceByAppendPointer(testSlice *[]int){ *testSlice = append(*testSlice, 22) } func main(){ testSlice := make([]int, 2, 3) testSlice[0] = 0 testSlice[1] = 1 fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice) //len: 2, cap: 3, data:[0 1] setSlice(testSlice) fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice) //len: 2, cap: 3, data:[10 11] //因为slice中的array是指针类型所以在参数传递中,可以修改slice中array的值 setSliceByAppend(testSlice) fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice) //len: 2, cap: 3, data:[10 11] setSliceByAppendPointer(&testSlice) fmt.Printf("len: %d, cap: %d, data:%+v \n", len(testSlice), cap(testSlice), testSlice) //len: 3, cap: 3, data:[10 11 22] //由setSliceByAppend和setSliceByAppendPointer的测试可以得知, //使用append()来修改slice的值,会生成一个新的slice,新的slice内存地址和原来的就不一样了。 //如果需要使用append()来修改slice的值,需要使用指针类型的slice。 } ``` --- 参考网址: https://www.jb51.net/article/136199.htm https://blog.golang.org/go-slices-usage-and-internals http://www.cnblogs.com/hutusheng/p/5492418.html

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

626 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传