Go语言多层字符串Map问题:重复校验时值被覆盖如何解决?
问题分析与解决
嘿,我来帮你排查这个问题~你的代码里出现覆盖问题的根源很明确:每次发现某个requestNo不存在时,你都会创建一个全新的子Map并覆盖掉当前Session对应的已有子Map,这就导致之前存储的其他requestNo全部丢失了。
具体问题拆解
我们拿你第二次调用chkDuplicate(mySessionData, "session1", "2")的场景来分析:
- 此时
mySessionData["session1"]已经存在,对应的是存储了"1":true的子Map。 - 你的代码执行
val, found := m[sess][Reqno]时,因为"2"不在子Map里,所以found为false。 - 接着你创建了一个新的子Map
valu := make(map[string]bool),把"2":true放进去,然后直接赋值给m[sess]——这就把原来存储"1":true的子Map给完全覆盖了!
修正后的代码
下面是修复后的完整代码,核心是先判断Session对应的子Map是否存在,不存在才创建;如果存在,直接在已有子Map里操作即可:
package main import "fmt" func main() { mySessionData := make(map[string]map[string]bool) ret := chkDuplicate(mySessionData, "session1", "1") fmt.Println("是否重复:", ret, " 当前Map:", mySessionData) ret = chkDuplicate(mySessionData, "session1", "2") fmt.Println("是否重复:", ret, " 当前Map:", mySessionData) ret = chkDuplicate(mySessionData, "session1", "3") fmt.Println("是否重复:", ret, " 当前Map:", mySessionData) ret = chkDuplicate(mySessionData, "session1", "2") fmt.Println("是否重复:", ret, " 当前Map:", mySessionData) ret = chkDuplicate(mySessionData, "session1", "4") fmt.Println("是否重复:", ret, " 当前Map:", mySessionData) delete(mySessionData, "session1") fmt.Println("删除session1后:", mySessionData) } func chkDuplicate(m map[string]map[string]bool, sess string, reqNo string) bool { // 第一步:先检查当前Session对应的子Map是否存在 sessionReqMap, sessionExists := m[sess] if !sessionExists { // 如果Session不存在,创建新的子Map并关联到主Map sessionReqMap = make(map[string]bool) m[sess] = sessionReqMap } // 第二步:检查当前requestNo是否已经存在于子Map中 reqExists := sessionReqMap[reqNo] if reqExists { // 存在,返回true表示重复 return true } // 不存在,将requestNo加入子Map,返回false表示不重复 sessionReqMap[reqNo] = true return false }
运行结果说明
执行这段代码后,你会看到:
- 前三次调用(添加1、2、3)都返回
false,mySessionData["session1"]会逐步包含"1"、"2"、"3"三个键。 - 第四次调用(重复添加2)返回
true,mySessionData不会被修改。 - 第五次调用(添加4)返回
false,mySessionData["session1"]新增"4"键。 - 最后删除
session1后,主Map变回空。
额外小提示
如果你的代码需要在并发场景下使用,这个Map不是线程安全的,需要用sync.RWMutex来加锁保护,避免出现竞态条件。不过如果是单线程场景,上面的代码就完全够用啦~
内容的提问来源于stack exchange,提问作者Deepak Kumar
相关产品推荐
相关产品推荐

