go语言数组删除 go struct数组( 二 )


map的扩容
当以上的哈希表增长的时候 , Go语言会将bucket数组的数量扩充一倍,产生一个新的bucket数组 , 并将旧数组的数据迁移至新数组 。
加载因子
判断扩充的条件,就是哈希表中的加载因子(即loadFactor) 。
加载因子是一个阈值,一般表示为:散列包含的元素数 除以 位置总数 。是一种“产生冲突机会”和“空间使用”的平衡与折中:加载因子越小,说明空间空置率高 , 空间使用率?。?但是加载因子越大,说明空间利用率上去了,但是“产生冲突机会”高了 。
每种哈希表的都会有一个加载因子 , 数值超过加载因子就会为哈希表扩容 。
Golang的map的加载因子的公式是:map长度 / 2^B(这是代表bmap数组的长度,B是取的低位的位数)阈值是6.5 。其中B可以理解为已扩容的次数 。
当Go的map长度增长到大于加载因子所需的map长度时,Go语言就会将产生一个新的bucket数组,然后把旧的bucket数组移到一个属性字段oldbucket中 。注意:并不是立刻把旧的数组中的元素转义到新的bucket当中 , 而是,只有当访问到具体的某个bucket的时候,会把bucket中的数据转移到新的bucket中 。
如下图所示:当扩容的时候,Go的map结构体中,会保存旧的数据,和新生成的数组
上面部分代表旧的有数据的bucket,下面部分代表新生成的新的bucket 。蓝色代表存有数据的bucket,橘黄色代表空的bucket 。
扩容时map并不会立即把新数据做迁移,而是当访问原来旧bucket的数据的时候,才把旧数据做迁移,如下图:
注意:这里并不会直接删除旧的bucket,而是把原来的引用去掉,利用GC清除内存 。
map中数据的删除
如果理解了map的整体结构,那么查找、更新、删除的基本步骤应该都很清楚了 。这里不再赘述 。
值得注意的是,找到了map中的数据之后,针对key和value分别做如下操作:
1
2
3
4
1、如果``key``是一个指针类型的,则直接将其置为空,等待GC清除;
2、如果是值类型的,则清除相关内存 。
3、同理,对``value``做相同的操作 。
4、最后把key对应的高位值对应的数组index置为空 。
go语言中数组使用的注意事项和细节1、数组是多个 相同类型 的数据的组合 , 一个数组一旦声明/定义了,其 长度是固定的,不能动态变化。
【go语言数组删除 go struct数组】 2、var arr []int这时arr就是一个slice 切片。
3、数组中的元素可以是任何数据类型 , 包括值类型和引用类型,但是 不能混用。
4、数组创建后,如果没有赋值,有默认值如下:
数值类型数组:默认值为 0
字符串数组:默认值为 ""
bool数组:默认值为 false
5、使用数组的步骤:
(1)声明数组并开辟空间
(3)给数组各个元素赋值
(3)使用数组
6、数组的下标是从0开始的 。
7、数组下标必须在指定范围内使用,否则报panic:数组越界,比如var arr [5]int的有效下标为0~4.
8、Go的数组属于 值类型 ,在默认情况下是 值传递 ,因此会进行值拷贝 。数组间不会相互影响 。
9、如想在其他函数中去修改原来的数组,可以使用 引用传递 (指针方式) 。
10、长度是数组类型的一部分 , 在传递函数参数时,需要考虑数组的长度,看以下案例:
题1:编译错误,因为不能把[3]int类型传递给[]int类型,前者是数组,后者是切片;
题2:编译错误,因为不能把[3]int类型传递给[4]int类型;
题3:编译正确,因为[3]int类型传给[3]int类型合法 。

推荐阅读