Я хочу иметь функцию проверки дубликатов ключей на разных картах.
Это то, что у меня есть
ma := map[string]typeA
mb := map[string]typeB
mc := map[string]typeC
dup := map[string]bool{}
for k := range ma{
if !dup[k] {
dup[k] = true
} else {
return fmt.Errorf("duplicate key[%v]", k)
}
}
for k := range mb{
if !dup[k] {
dup[k] = true
} else {
return fmt.Errorf("duplicate key[%v]", k)
}
}
for k := range mc {
if !dup[k] {
dup[k] = true
} else {
return fmt.Errorf("duplicate key[%v]", k)
}
}
return nil
Я хочу реорганизовать это, и я пишу функцию
func checkDupKeys[M ~map[K]V, K comparable, V any](maps ...M) error {
dup := map[K]bool{}
for _, m := range maps {
for k := range m {
if !dup[k] {
dup[k] = true
} else {
return fmt.Errorf("duplicate key[%v]", k)
}
}
}
return nil
}
Но он может принимать карты только одного типа, а не типа A, типа B и типа C.
Вы можете сделать что-то с картами .Ключи : func checkDupKeys[K comparable](keys ...[]K) {}; checkDupKeys(maps.Keys(ma), maps.Keys(mb), maps.Keys(mc))
.
Если бы я хотел реализовать эту функцию, я бы выбрал другой подход.
package main
import (
"fmt"
"reflect"
)
func main() {
ma := map[string]int{"one": 1, "two": 2}
mb := map[string]string{"one": "one"}
mc := map[string]float64{"one": 1.1}
fmt.Println(checkDupKeys(ma, mb, mc))
}
func checkDupKeys(maps ...any) error {
dup := map[string]bool{}
for _, m := range maps {
v := reflect.ValueOf(m).MapKeys()
for _, k := range v {
if !dup[k.Interface().(string)] {
dup[k.Interface().(string)] = true
} else {
return fmt.Errorf("duplicate key[%v]", k)
}
}
}
return nil
}
Боюсь, что дженерики сами по себе недостаточно выразительны, чтобы позволить вам написать такую гибкую функцию.