goset
goset copied to clipboard
About Pointer value compare
Hey Amit Itzkovitch!
I have a struct value is pointer values , by obtan a set of value, two set of Struct with goset conpare value, owing to two struct property is different pointer, but the pointer value is equal, so goset.Contains(item)
always false. Can have conpare Struct Pointer values?
The data struct is two way
- package: `github.com/haproxytech/models
- datastruct:
models.Server
Phenomenon: goset.Contains() conpare the pointer address, not pointer value.
Hi @cylonchau! Why won't you make the Set contain the actual value instead of a pointer to the value?
The Set object is designed to allow O(1) access, for both Contains()
and Add()
. It is implemented using a map, and all the values are stored as map keys. What you are asking for requires iterating over all the items, which kind of loses the main feature of the Set.
So I suggest you just store the values inside set set.Add(*item)
, and then do goset.Contains(*item)
Hi @cylonchau! Why won't you make the Set contain the actual value instead of a pointer to the value?
The Set object is designed to allow O(1) access, for both
Contains()
andAdd()
. It is implemented using a map, and all the values are stored as map keys. What you are asking for requires iterating over all the items, which kind of loses the main feature of the Set.So I suggest you just store the values inside set
set.Add(*item)
, and then dogoset.Contains(*item)
It's not this scenes, it is this scenes
the data struct is
type a struct {
a1 int
b1 *int64
}
goset opreation
type_a := getAstruct() // will get a values struct a { a1 = 1; b1= 2 }; but b1 pointer address = 0x0001
p = int64(1) // suppose the variable p address is 0x0002
type_b := a{a1: 1, b1:&p}
goset.Add(type_b)
goset.Contains(type_a) // false, because 0x0001 != 0x0002, the goset.Contains conpare pointer address, not pointer value
In the theory type_a == type_b
, but attributes b1
is a pointer , the pointer address is diffrent value. So the goset.Contains always false.
If the goset element is a struct, and the struct attribute has pointer type, then goset.Contains always false. Because when we are comparing two element, for lookup with goset, the goset.Contains(attr)
, The address of pointer attribute of attr always no equal the address of pointer attribute of goset element
Thanks for clarifying the issue @cylonchau.
I feel your pain, as although logically the two instances have the same values, they are not equal because of the pointer to a different memory address. The thing is, this is how pointers work, and there's not much to do about that...
If you take a look at goset
's implementation, you can see it is implemented using a map, where the keys of the map are the items of the Set. goset
doesn't really implement any comparison itself, it just adds/deletes keys from the map. And because of how structs are handled as map keys, pointer fields are considered by the memory address and not by the value they are pointing to.
This makes this issue not trivial to solve. It requires providing a way to define a custom hash function for that struct you are using and requires changing the Set implementation in a way that will make it heavier performance-wise.
Having said all that, I am interested to hear what are your suggestions for this pointer-fields problem. How do you imagine such a solution to look like?
Thank you @amit7itz
I used other unpointer type resoved this problem, but pointer nature so. compare pointer value maybe is the goset point of improvement