浅谈golang切片切片原理

  

<>强片介绍
  

  

数组的长度在定义之后无法再次修改,数组是值类型,每次传递都将产生一份副本。显然这种数据结构无法完全满足开发者的真实需求。在初始定义数组时,我们并不知道需要多大的数组,因此我们就需要“动态数组”。在去里面这种数据结构叫切片,切片并不是真正意义上的动态数组,而是一个引用类型.slice总是指向一个底层数组,切片的声明也可以像数组一样,只是不需要长度,它是可变长的,可以随时往片里面加数据。
  

  

初看起来,数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是个指针。数组切片的数据结构可以抽象为以下3个变量:
  

  

1。一个指向原生数组的指针(点):指向数组中片指定的开始位置;
  2.数组切片中的元素个数(len):即片的长度;
  3.数组切片已分配的存储空间(cap):也就是片开始位置到数组的最后位置的长度。
  

  

从底层实现的角度来看,数组切片实际上仍然使用数组来管理元素,基于数组,数组切片添加了一系列管理功能,可以随时动态扩充存放空间,并且可以被随意传递而不会导致所管理的元素被重复复制。
  

  

<>强片声明
  

  

声明片时方括号[]内没有任何数据
  声明一个元素类型为int的片
  var mySlice [] int ,,声明两个元素类型为字节的slice ,,

  

golang中的部分非常强大,让数组操作非常方便高效。在开发中不定长度表示的数组全部都是片。但是很多同学对切片的模糊认识,造成认为golang中的数组是引用类型,结果就是在实际开发中碰到很多坑,以至于出现一些莫名奇妙的问题,数组中的数据丢失了。

  

下面我们就开始详细理解下片、理解后会对开发出高效的程序非常有帮助。

  

这个是切片的数据结构,它很简单,一个指向真实数组地址的指针ptr,片的长度len和容量上限。

  

浅谈golang切片切片原理

  

其中兰和帽就是我们在调用len(片)和帽(片)返回的值。

  

我们来按照片的数据结构定义来解析出ptr, len,帽

     //按照上图定义的数据结构   类型片结构{   ptr不安全。//数组指针的指针   len int//片长度   帽int//片的能力   }      

下面写一个完整的程序,尝试把golang中片的内存区域转换成我们定义的切进行解析

        主要包      导入(   “fmt”   “不安全”   )//按照上图定义的数据结构   类型片结构{   ptr不安全。//数组指针的指针   len int//片长度   帽int//片的能力   }//因为需要指针计算,所以需要获取int的长度//32位整数长度=4//64位整数长度=8   var intLen=int (unsafe.Sizeof (int (0)))      函数main () {   s:=(int []、10、20)//利用指针读取片记忆的数据   如果intLen==4{//32位   m:=*(* 4 + 4 * 2字节)(unsafe.Pointer (,))   fmt。Println(“片记忆:“米)   其他}{//64位   m:=*(*(8 + 8 * 2)字节)(unsafe.Pointer (,))   fmt。Println(“片记忆:“米)   }//把片转换成自定义的片结构   片:=(*片)(unsafe.Pointer (,))   fmt。Println(“片结构:“片)   fmt。Printf (" ptr: % v len: % v帽:% v \ n”, slice.ptr,切片。len slice.cap)   fmt。Printf (" golang片len: % v帽:% v \ n”, len (s),帽(s))      s [0]=0   [1]=1   [2]=2//转成数组输出   加勒比海盗:=* (* [3]int) (unsafe.Pointer (slice.ptr))   fmt。Println(“数组值:“arr)//修改片的莱恩   片。len=15   fmt。Println(“切兰:“slice.len)   fmt。Println (“golang片兰:“,len (s))   }      之前      

运行一下查看结果

        美元去运行slice.go      片记忆:[0 64 6 32 200 0 0 0 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0]   片结构:,{0 xc820064000 10 20}   ptr: 0 xc820064000 len: 10帽:20   golang片len: 10帽:20   数组的值(0 1 2):   片len: 15   golang片len: 15   之前      

看到了,golang片的记忆内容,和自定义的切片的值,还有按照切片中的指针指向的内存,就是实际数组数据。当修改了切片中的len, len (s)也变了。

  

接下来结合几个例子,了解下片一些用法

  

浅谈golang切片切片原理