如何实现可检查不同类型Go map重复键的通用函数
检查不同值类型的string键map重复键的实现方案
针对你需要检查键为string、值类型任意的多个map之间重复键的需求,这里提供两种可行方案:
方案一:基于反射的通用实现(调用简单)
这种方式无需泛型,直接通过反射处理任意键为string的map,能适配所有值类型:
import "reflect" func CheckDupKeys(maps ...interface{}) []string { keySet := make(map[string]bool) duplicateKeys := make(map[string]bool) for _, m := range maps { // 校验输入是否为map且键类型为string mt := reflect.TypeOf(m) if mt.Kind() != reflect.Map || mt.Key().Kind() != reflect.String { panic("only map[string]T type is allowed") } // 提取所有键并检查重复 mv := reflect.ValueOf(m) for _, k := range mv.MapKeys() { keyStr := k.String() if keySet[keyStr] { duplicateKeys[keyStr] = true } else { keySet[keyStr] = true } } } // 转换为切片返回结果 result := make([]string, 0, len(duplicateKeys)) for k := range duplicateKeys { result = append(result, k) } return result }
使用示例
type TypeA struct{} type TypeB struct{} type TypeC struct{} func main() { ma := map[string]TypeA{"id1": {}, "id2": {}} mb := map[string]TypeB{"id2": {}, "id3": {}} mc := map[string]TypeC{"id1": {}, "id4": {}} dupes := CheckDupKeys(ma, mb, mc) // 输出:["id1" "id2"] }
方案二:纯泛型实现(类型安全)
如果不想依赖反射,可通过泛型先收集每个map的键,再统一检查重复,编译期就能确保输入类型合法:
// 收集单个map[string]T的所有键 func CollectStringMapKeys[T any](m map[string]T) []string { keys := make([]string, 0, len(m)) for k := range m { keys = append(keys, k) } return keys } // 检查多组键的重复项 func CheckDupKeysFromKeyGroups(keyGroups ...[]string) []string { keySet := make(map[string]bool) duplicateKeys := make(map[string]bool) for _, keys := range keyGroups { for _, k := range keys { if keySet[k] { duplicateKeys[k] = true } else { keySet[k] = true } } } result := make([]string, 0, len(duplicateKeys)) for k := range duplicateKeys { result = append(result, k) } return result }
使用示例
func main() { ma := map[string]TypeA{"id1": {}, "id2": {}} mb := map[string]TypeB{"id2": {}, "id3": {}} mc := map[string]TypeC{"id1": {}, "id4": {}} dupes := CheckDupKeysFromKeyGroups( CollectStringMapKeys(ma), CollectStringMapKeys(mb), CollectStringMapKeys(mc), ) // 输出:["id1" "id2"] }
方案对比
- 反射方案:调用更简洁,直接传入所有map,但运行时才会检查输入类型合法性,非法输入会触发panic。
- 纯泛型方案:编译期就能校验输入类型,更安全,但需要先调用收集函数处理每个map。
内容的提问来源于stack exchange,提问作者Evilolipop
相关产品推荐
相关产品推荐

