切片
- 切片结构
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
}