Go语言递归生成定长排列存入map时出现键值不一致问题
问题根因
这个问题是Go切片的底层数组共享特性导致的:
- Go的切片本身是引用类型,存储的是指向底层数组的指针、长度、容量三个属性,你直接把切片存入map时,存的是引用而非切片内容的拷贝
- 递归调用时你用
append(Q, states[i])生成新切片传递,当append操作不需要扩容时,新切片会和原切片共享同一个底层数组。后续递归对这个底层数组的修改,会同步影响到所有指向同一个底层数组的、已经存入map的切片 - 你示例中首次存入键
aaaa对应的切片后,下一轮递归修改了该切片共享的底层数组的最后一位元素为b,就出现了键aaaa对应值变成[a a a b]的异常
修复方法
你只需要在将切片存入map前,对当前切片做一次深拷贝即可,修改递归终止分支的代码:
if k == 0 { key := strings.Join(Q, "") // 生成独立的切片拷贝再存入map,避免后续修改影响已存储的内容 copyQ := make([]string, len(Q)) copy(copyQ, Q) QQM[key] = copyQ fmt.Println(QQM) return }
内容的提问来源于stack exchange,提问作者Jonas Knobloch
相关产品推荐
相关产品推荐

