In an attempt to have more useful enums in Go, I've tried using struct pointers as enum values. This works great if the struct has fields, but for the empty struct I sometimes get the same pointer multiple times, regardless of whether I use &Foo{}
or new(Foo)
.
Is there any way I can force the pointers to be different?
This is what I'm trying to do ( try it online ):
package main
type Foo struct{}
var FooValues = struct {
Alpha *Foo
Bravo *Foo
Charlie *Foo
}{
Alpha: &Foo{}, // These pointers should all be different
Bravo: &Foo{}, // But sometimes
Charlie: &Foo{}, // They are not
}
func main() {
if FooValues.Alpha == FooValues.Charlie {
panic("enum values are the same!")
}
}
Is there any way I can force the pointers to be different?
No. Any implementation is allowed to use the same address. You must redesign.
From the Go language specification :
Pointers to distinct zero-size variables may or may not be equal.
This seems to do it:
package main
type foo struct{}
func newFoo() *foo {
return new(foo)
}
type fooValues struct { alpha, bravo, charlie *foo }
func newFooValues() fooValues {
return fooValues{
newFoo(), newFoo(), newFoo(),
}
}
func main() {
f := newFooValues()
if f.alpha == f.charlie {
panic("enum values are the same!")
}
}
As mentioned, pointer comparison for zero-sized types is not reliable in this way.
Replace
type Foo struct{}
with
type Foo struct{int}
Now your code works. The added cost is ~1 word of memory per enum that you allocate, which should be negligible in most cases.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.