踩了for range无序map和make切片的坑 | 青训营笔记

123 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 17 天

先说说问题的起因,我在测试功能准备提交大项目的时候,发现关注列表和粉丝列表的顺序不对,按理说最新关注的排在前面才对,所以我准备动手修复一下这个小问题,没想到问题却不小,耽误了不少时间。

起初我看队员的代码没加order by做排序,我以为是这个问题,我加上,然后测试,发现事情有点诡异,出现了另外一个奇怪的bug,排序一会正常,一会又不正常,非常诡异,我就纳闷了,这到底咋回事?

直到看到看到如下代码,我才恍然大悟,由于之前一位队友写的这两个接口bug太多,什么粉丝关注,我关注,取消关注,显示关注列表,关注状态等等,问题太多了,然后我重写了一下service和dao层的代码,所以这个问题是我修bug的时候修出来的,没错,这是我写的(笑哭)。

for _, id := range userMap {
   userMap[id].IsFollow, _ = svc.dao.IsFollow(myUid, userMap[id])
   userList = append(userList, userMap[id])
}

这段代码会出现的问题就是,我用order by排好的序,因为Go语言的map无序特性,导致排好的序又乱了....emmm

知道问题在哪就好改了,代码如下:

for i := 0; i < len(idList); i++ {
   userMap[idList[i]].IsFollow, _ = svc.dao.IsFollow(myUid, userMap[idList[i]].ID)
   userList = append(userList, userMap[idList[i]])
}

但是紧接着又出现了另外一个bug...

这段代码用到一个idList,这个切片就出大问题了,该切片的代码如下:

idList := make([]uint, len(userIdList))
for i := 0; i < len(userIdList); i++ {
   idList[i] = append(idList, userIdList[i].UserID)
}

嗯嗯,这段是另外一个队友写的,我cv过来用用,然后就出问题了,和上面那段代码结合,就会出现空指针的panic。

这是怎么回事呢?

根据我研究,发现是append的问题,首先我们make一个uint的切片,长度和容量的大小都是len(userIdList),看起来没问题,往下看append这里,加入我们有个userIdList是2,里面数据是5,7,此时初始化的idList这个切片就是[0,0],我们append后,就变成了[0,0,5,7],问题浮现而出,我们上面索引idList,但是这里idList里面有len长度的0值,导致空指针panic。

至此,问题迎刃而解。