我想创建一个" set"我的应用程序中使用的gorm类型。因此,我想将map
定义为我的类型gorm.DB
作为键,并将structs{}
作为标记清空:
var (
autoMigrations map[gorm.DB]struct{}
)
但编译器不允许我这样做,但错误:invalid map key type gorm.DB
。我可以使用指向gorm.DB
的指针欺骗它,如:
map[*gorm.DB]struct{}
但它不是一个解决方案,因为我需要使它独一无二,如果我的地图像db.AutoMigrate(&Chat{})
一样被填充,我可以获得许多具有不同地址的类似对象。
另一种解决方案是制作一片gorm.DB
:
autoMigrations []gorm.DB
但我必须手动过滤添加元素,这似乎有点疯狂。
答案 0 :(得分:1)
您只能在地图Spec: Map types:中使用类型作为键。 comparison operators
必须为密钥类型的操作数完全定义blank ==和!=;因此,键类型不能是函数,映射或切片。
gorm.DB
是一个结构,只有当所有字段都具有可比性时,结构值才具有可比性:
如果所有字段都具有可比性,则结构值具有可比性。如果相应的非
reflect.Type
字段相等,则两个struct值相等。
但gorm.DB
有例如DB.values
字段是地图类型,地图不可比较,因此gorm.DB
值也不具有可比性,因此您无法将其用作地图关键字。
如果要创建一组类型,则应使用reflect.TypeOf()
作为地图键,您可以使用Go Playground从该类型的值中获取该地图键。
一个小技巧,如果你想要reflect.Type
而不必创建相关类型的值,你可以从该类型的指针值(可能是nil
)开始,并且使用Type.Elem()
获取指向类型的reflect.Type
描述符。
例如,要获取结构类型reflect.Type
的{{1}}描述符而不实际创建/拥有Point struct{ X, Y int }
:
Point
打印type Point struct{ X, Y int }
tpoint := reflect.TypeOf((*Point)(nil)).Elem()
fmt.Println(tpoint)
。在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?
{{3}}