How to compare the identity of maps OR what's going on in this example?

假装没事ソ 提交于 2021-02-04 20:38:12

问题


I'm trying to compare the identity of 2 maps

package main

import "fmt"

func main() {
    a := map[int]map[int]int{1:{2:2}}

    b := a[1]
    c := a[1]

    // I can't do this: 
    // if b == c
    // because I get: 
    // invalid operation: b == c (map can only be compared to nil)

    // but as far as I can tell, mutation works, meaning that the 2 maps might actually be identical
    b[3] = 3

    fmt.Println(c[3]) // so mutation works...


    fmt.Printf("b as pointer::%p\n", b)
    fmt.Printf("c as pointer::%p\n", c) 

    // ok, so maybe these are the pointers to the variables b and c... but still, those variables contain the references to the same map, so it's understandable that these are different, but then I can't compare b==c like this
    fmt.Printf("&b::%p\n", &b)
    fmt.Printf("&c::%p\n", &c)  

    fmt.Println(&b == &c)
}

this produces the following output:

3
b as pointer::0x442280
c as pointer::0x442280
&b::0x40e130
&c::0x40e138
false

What's especially confusing to me is that while b as pointer::0x442280 and c as pointer::0x442280 seem to have the same values, which indeed would confirm to me my suspicion that those variables somehow point to the same dict.

So does anyone know how I can make go tell be that b and c are "the same object"?


回答1:


Not pretty but you can use reflect.ValueOf(b).Pointer():

package main

import (
    "fmt"
    "reflect"
)

func main() {
    a := map[int]map[int]int{1: {2: 2}}

    b := a[1]
    c := a[1]

    d := map[int]int{2: 2}

    fmt.Println(reflect.ValueOf(b).Pointer() == reflect.ValueOf(c).Pointer())
    fmt.Println(reflect.ValueOf(c).Pointer() == reflect.ValueOf(d).Pointer())
}



回答2:


Ok, so I'm obviously new to the language, and I won't start criticizing it so soon, but this is the solution I found:

Python code:

obj1 is obj2

Javascript code:

obj1 === obj2  // for objects, which is what I care about

Java code:

obj1 == obj2

And then there's go code:

fmt.Sprintf("%p", obj1) == fmt.Sprintf("%p", obj2)

Yes, it's exactly what it looks like: I get the string representation of pointers to the 2 variables, and compare those. And the strings look like this 0x442280.

fmt.DeepEqual is not the solution for me, because

  1. it checks whether the pointers are equal and then
  2. it then checks whether the values in the map are equal

This is completely not what I want. I want to know only if the maps are exactly the same object, not wether they contain the same values



来源:https://stackoverflow.com/questions/52990608/how-to-compare-the-identity-of-maps-or-whats-going-on-in-this-example

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!