切片、Map和string原理分析

切片

  • 切片结构
type slice struct {
array unsafe.Pointer
len int
cap int
}
  • 指针+长度+容量=3*8=24字节

string

  • string结构
type stringStruct struct {
str unsafe.Pointer
len int
}
  • 指针+长度=8+8=16字节

  • 字符串构建过程是先跟据字符串构建stringStruct,再转换成string。

  • []byte转string 和 string转[]byte 均为申请内存空间,然后拷贝

  • 字符串拼接

      新字符串的内存空间是⼀次分配完成的,所以性能消耗主要在拷⻉数据上。
      拼接过程需要遍历两次切⽚,第⼀次遍历获取总的字符串⻓度,据此申请内存,第⼆次遍历会把字符串逐个拷⻉过去。
      实现过程为:使⽤rawstring()⽅法初始化⼀个指定⼤⼩的string,同时返回⼀个切⽚,⼆者共享同⼀块内存空间,后⾯向切⽚中拷⻉数据,也就间接修改了string。
    
  • 为什么字符串不允许修改

      因为Go的实现中, string不包含内存空间,只有⼀个内存的指针,这样做的好处是string变得⾮常轻量。
    
  • []byte转换成string⼀定会拷⻉内存吗?

      有时候只是临时需要字符串的场景下, byte切⽚转换成string时并不会拷⻉内存,⽽是直接返回⼀个string,这个string的指针(string.str)指向切⽚的
    

内存。

  • string和[]byte的使用场景

      string 擅⻓的场景:
      		需要字符串⽐较的场景;
      		不需要nil字符串的场景;
      []byte擅⻓的场景:
      		修改字符串的场景,尤其是修改粒度为1个字节;
      		函数返回值,需要⽤nil表示含义的场景;
      		需要切⽚操作的场景;
    

Map

  • bucket结构
type hmap struct {
count int //map中的元素个数,必须放在 struct的第⼀个位置,因为 内置的len函数会
从这⾥读取
flags uint8
B uint8 // 说明包含2^B个bucket
noverflow uint16 // 溢出的bucket的个数
hash0 uint32 // hash种⼦
buckets unsafe.Pointer // buckets的数组指针
oldbuckets unsafe.Pointer // 结构扩容的时候⽤于复制的buckets数组
nevacuate uintptr // 搬迁进度(已经搬迁的buckets数量)
extra *mapextra
}
  • 待补充
发布了40 篇原创文章 · 获赞 26 · 访问量 7662

猜你喜欢

转载自blog.csdn.net/weixin_44879611/article/details/104906819