Golang Slice和map的坑
一、浅拷贝同根
func main() { nums := [3]int{} nums[0] = 1 fmt.Printf("nums: %v , len: %d, cap: %d\n", nums, len(nums), cap(nums)) dnums := nums[0:2] dnums[0] = 5 fmt.Printf("nums: %v ,len: %d, cap: %d\n", nums, len(nums), cap(nums)) fmt.Printf("dnums: %v, len: %d, cap: %d\n", dnums, len(dnums), cap(dnums)) }
输出:
nums: [1 0 0] , len: 3, cap: 3
nums: [5 0 0] ,len: 3, cap: 3
dnums: [5 0], len: 2, cap: 3
slice若不是深拷贝或者重新生成新空间,无论通过参数传递还是使用 := 或者 [:]赋值都存在同根性。
二、扩容摆脱同根
Slice与Array最大的区别在于Slice不需要指定大小会自动扩容等一些特性,我们在接受并习惯同根性后。Slice在多次append元素时,若满足扩容策略,这时候内部就会重新申请一块内存空间,将原本的元素拷贝一份到新的内存空间上。此时其与原本的数组就没有任何关联关系了,再进行修改值也不会变动到原始数组。
func main() { nums := [3]int{} nums[0] = 1 fmt.Printf("nums: %v , len: %d, cap: %d\n", nums, len(nums), cap(nums)) dnums := nums[0:2] dnums = append(dnums, []int{2, 3}...) dnums[1] = 1 fmt.Printf("nums: %v ,len: %d, cap: %d\n", nums, len(nums), cap(nums)) fmt.Printf("dnums: %v, len: %d, cap: %d\n", dnums, len(dnums), cap(dnums)) }
输出 :
nums: [1 0 0] , len: 3, cap: 3
nums: [1 0 0] ,len: 3, cap: 3
dnums: [1 1 2 3], len: 4, cap: 6
三、Empty与nil
Empty
func main() { nums := []int{} renums := make([]int, 0) fmt.Printf("nums: %v, len: %d, cap: %d\n", nums, len(nums), cap(nums)) fmt.Printf("renums: %v, len: %d, cap: %d\n", renums, len(renums), cap(renums)) }
输出:
nums: [], len: 0, cap: 0
renums: [], len: 0, cap: 0
nil
func main() { var nums []int fmt.Println(nums,len(nums),cap(nums)) }
输出
[] 0 0
通过输出来看我们会发现不管是数据还是len 和cap都是相同的输出内容。
那我们就来用代码来证明一下他们是否真的一致
func main() { var nums []int renums := make([]int, 0) if nums == nil { fmt.Println("nums is nil.") } if renums == nil { fmt.Println("renums is nil.") } }
输出:
nums is nil.
输出结果是不是出乎意料!不过聪明如你肯定已经通过自己的经验想到了答案。
一个有分配空间(Empty)一个没有分配空间(nil)
以上就是我使用slice遇到的坑,这里不再针对map做特殊分析了。
到此这篇关于Golang Slice和map的坑的文章就介绍到这了,更多相关Golang Slice和map内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
解析GOROOT、GOPATH、Go-Modules-三者的关系
这篇文章主要介绍了解析GOROOT、GOPATH、Go-Modules-三者的关系,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2020-10-10
最新评论