make slice 后 append 产生的问题

今天又踩到了一个 go 语言的坑,其实也不算坑,本质上还是自己对这门语言的不熟悉。

来看一下我犯的错误,直接上代码:

1
2
3
4
5
6
7
func Int64ToStrings(ids []int64) []string {
strs := make([]string, len(ids))
for i, id := range ids {
strs = append(strs, strconv.FormatInt(id, 10))
}
return strs
}

我的需求很简单,将一个 int64 的切片转为 string 类型的切片,写这段代码的时候想到可以预先分配 slice 的大小,所以写了开头的 make,后边就直接逐个将转为 string 的元素 append 进去了。

但是,make 时实际已经帮我完成了里边指定数量元素的初始化,即:

1
s = make([]string, 5) // s == []string{"", "", "", "", ""}

所以我之后再往里边 append 时是往最后一个空字符串后边追加元素。

修复后的代码如下:

1
2
3
4
5
6
7
func Int64ToStrings(ids []int64) []string {
strs := make([]string, len(ids))
for i, id := range ids {
strs[i] = strconv.FormatInt(id, 10)
}
return strs
}

或者在初始化时指定 slice 长度为0,容量为我们需要的长度:

1
2
3
4
5
6
7
func Int64ToStrings(ids []int64) []string {
strs := make([]string, 0, len(ids))
for i, id := range ids {
strs = append(strs, strconv.FormatInt(id, 10))
}
return strs
}