3 回答
TA贡献1936条经验 获得超7个赞
我想要一个通用方法。
现在Go 1.18和泛型在这里,你可以写这样一个泛型函数;见下文和这个游乐场。通常不鼓励进行反射,实现此功能不需要反射。
package main
import "fmt"
func IsMapSubset[K, V comparable](m, sub map[K]V) bool {
if len(sub) > len(m) {
return false
}
for k, vsub := range sub {
if vm, found := m[k]; !found || vm != vsub {
return false
}
}
return true
}
type MyMap map[string]string
func main() {
a := map[string]string{"a": "b", "c": "d", "e": "f"}
b := map[string]string{"a": "b", "e": "f"}
c := map[string]string{"a": "b", "e": "g"}
fmt.Println(IsMapSubset(a, b))
fmt.Println(IsMapSubset(a, c))
fmt.Println(IsMapSubset(MyMap(a), c))
}
输出:
true
false
不过,关于NaN的常见警告适用。
TA贡献1895条经验 获得超7个赞
Value.MapIndex() 返回一个反射。值,它是一个结构,不是结构的有效值。不能将结构值与 进行比较。nilnil
Value.MapIndex()声明:
如果在映射中找不到键,或者如果 v 表示 nil 映射,则返回零值。
因此,要判断是否在映射中找不到该键,请检查返回的键是否为其零值。为此,您可以使用 Value.IsValid() 方法。reflect.Value
您也不能(不应该)比较值。而是使用 Value.Interface() 获取其包装值,并对其进行比较。reflect.Value
if v2 := mapSetValue.MapIndex(k); !v2.IsValid() || v.Interface() != v2.Interface() { return false}测试它:
a := map[string]string{"a": "b", "c": "d", "e": "f"}
b := map[string]string{"a": "b", "e": "f"}
fmt.Println(IsMapSubset(a, b))
c := map[string]string{"a": "b", "e": "X"}
fmt.Println(IsMapSubset(a, c))输出将是(在Go Playground上尝试):
truefalse
TA贡献1843条经验 获得超7个赞
这是工作解决方案,以防有人需要:
// IsMapSubset returns true if mapSubset is a subset of mapSet otherwise false
func IsMapSubset(mapSet interface{}, mapSubset interface{}) bool {
mapSetValue := reflect.ValueOf(mapSet)
mapSubsetValue := reflect.ValueOf(mapSubset)
if fmt.Sprintf("%T", mapSet) != fmt.Sprintf("%T", mapSubset) {
return false
}
if len(mapSetValue.MapKeys()) < len(mapSubsetValue.MapKeys()) {
return false
}
if len(mapSubsetValue.MapKeys()) == 0 {
return true
}
iterMapSubset := mapSubsetValue.MapRange()
for iterMapSubset.Next() {
k := iterMapSubset.Key()
v := iterMapSubset.Value()
value := mapSetValue.MapIndex(k)
if !value.IsValid() || v.Interface() != value.Interface() {
return false
}
}
return true
}
- 3 回答
- 0 关注
- 141 浏览
添加回答
举报
