I'd like to create a "set" of gorm types used in my application. So I'd like to define a map
with my types gorm.DB
as keys and empty structs{}
as flags:
var (
autoMigrations map[gorm.DB]struct{}
)
But compiler doesn't allow me do this with error: invalid map key type gorm.DB
. I can fool it using pointers to gorm.DB
s like:
map[*gorm.DB]struct{}
But it's not a solution, because I need to make it unique and if my map gets filled like db.AutoMigrate(&Chat{})
I can get lots of similar object with different addresses.
Another solution is to make a slice of gorm.DB
:
autoMigrations []gorm.DB
But I have to filter elements on addition manually, which seems insane a little bit.
You can only use types as keys in a map that are comparable. Spec: Map types:
The comparison operators == and != must be fully defined for operands of the key type; thus the key type must not be a function, map, or slice.
gorm.DB
is a struct, and struct values are only comparable if all their fields are comparable:
Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.
But gorm.DB
has e.g. a DB.values
field which is a map type, and maps are not comparble, and thus gorm.DB
values are not comparable either, and so you can't use it as map keys.
If you want to create a set of types, you should use reflect.Type
as the map keys, which you can acquire using reflect.TypeOf()
from a value of that type.
A little trick, if you want a reflect.Type
without having to create a value of the type in question, you can start from a pointer value of that type (which may be nil
), and use Type.Elem()
to get the reflect.Type
descriptor of the pointed type.
For example, to get the reflect.Type
descriptor of a struct type Point struct{ X, Y int }
without actually creating / having a Point
:
type Point struct{ X, Y int }
tpoint := reflect.TypeOf((*Point)(nil)).Elem()
fmt.Println(tpoint)
Which prints main.Point
. Try it on the Go Playground.
See related questions:
How can I prevent a type being used as a map key?
Why can't Go slice be used as keys in Go maps pretty much the same way arrays can be used as keys?
Set of structs in Go
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With