map [gorm.DB] struct {} {}给出了无效的映射键类型gorm.DB

时间:2017-11-08 09:04:32

标签: dictionary go key go-gorm hashable

我想创建一个" 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

但我必须手动过滤添加元素,这似乎有点疯狂。

1 个答案:

答案 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?

Set of structs in Go

{{3}}