【问题标题】:How to know if 2 go maps reference the same data [duplicate]如何知道2张地图是否引用相同的数据[重复]
【发布时间】:2019-10-31 03:52:30
【问题描述】:

Go 地图是对内部数据的引用。这意味着当“复制”地图时,它们最终会共享相同的参考,从而编辑相同的数据。这与拥有另一个具有相同项目的地图有很大不同。但是,我找不到任何方法来区分这两种情况。

import "fmt"
import "reflect"

func main() {
    a := map[string]string{"a": "a", "b": "b"}
    // b references the same data as a
    b := a
    // thus editing b also edits a
    b["c"] = "c"
    // c is a different map, but with same items
    c := map[string]string{"a": "a", "b": "b", "c": "c"}

    reflect.DeepEqual(a, b) // true
    reflect.DeepEqual(a, c) // true too
    a == b // illegal
    a == c // illegal too
    &a == &b // false
    &a == &c // false too
    *a == *b // illegal
    *a == *c // illegal too
}

有什么解决办法吗?

【问题讨论】:

  • 代码中的所有 3 个地图都包含相同的数据,因此它们是相等的。
  • 拜托,“我们现在包含相同的元素”和“无论你做什么修改我们都将拥有相同的元素”之间存在巨大差异。
  • 根据golang.org/ref/spec#Type_identity:“如果两个映射类型具有相同的键和元素类型,则它们是相同的。”因此reflect.DeepEqual() 返回true。而golang.org/ref/spec#Comparison_operators 声明:“切片、映射和函数值不可比较。”所以我不确定是否有办法显示bc 是不同的。此外,Dave Cheney 表明 map is not reference variable.
  • 没有区别。我不知道你想做什么。假设您的地图类型为map[string]**int。即使您使用不同的**int 填充地图,它们的值仍然可能指向相同的int 并通过一个“修改”另一个进行修改。 原因为什么地图值上的相等性未定义。这是某种 XY 问题吗?

标签: go go-map


【解决方案1】:

使用反射包将地图作为指针进行比较:

func same(x, y interface{}) bool {
    return reflect.ValueOf(x).Pointer() == reflect.ValueOf(y).Pointer()
}

在问题的地图上这样使用它:

fmt.Println(same(a, b)) // prints true
fmt.Println(same(a, c)) // prints false

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 2011-09-07
    相关资源
    最近更新 更多