Go:make 与 new,切片扩容,以及 range 变量的地址
new 和 make 都分配内存,返回的东西不一样。new 用于整数、字符串和数组,返回指针,分到的空间是零值。make 用于切片、map 和 channel,返回的就是这个值,而且已经按类型完成初始化。对一个还没 make 的 map 写入,会直接 panic。这不是零值和未初始化的细微差别,是能不能用。
数组和切片都能按下标访问,都有 len 和 cap。数组长度固定,越界就是越界。切片可以变长,但它自己不存元素,底下是一个数组。数组是值,切片是这个数组的视图。
把切片传进函数,如果函数里的 append 没有触发扩容,里面和外面仍指向同一块数组,修改外面看得到。一旦扩容,函数里得到的是新数组,外面的切片还指向旧的。调用方如果丢掉 append 的返回值,扩容后的结果就丢了。
容量小于 1024 时,扩容按 2 倍。达到 1024 以后按 1.25 倍。还放得下时,append 在原切片上追加,长度加一。放不下时先扩容,返回新切片。
for i, v := range s 里,i 和 v 在整个循环中是同一对变量,下一轮用新值覆盖,地址不变。循环里再启动 goroutine 时,不能把 &i 或 &v 直接传进去,否则各个 goroutine 读到的是循环结束时的值。每轮先拷到一个新变量,再把那个变量的地址传进去。