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

map[gorm.DB]struct{}{} gives invalid map key type gorm.DB

我想创建一个在我的应用程序中使用的 "set" gorm 类型。所以我想用我的类型 gorm.DB 定义一个 map 作为键,空 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

但是我必须在添加时手动过滤元素,这看起来有点疯狂。

您只能将类型用作映射中的键 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 是一个结构,结构值只有在它们的所有字段都可比较时才可比较:

Struct values are comparable if all their fields are comparable. Two struct values are equal if their corresponding non-blank fields are equal.

但是 gorm.DB 有例如DB.values 字段是地图类型,地图不可比较,因此 gorm.DB 值也不可比较,因此不能将其用作地图键。

如果您想创建一组类型,您应该从该类型的值中使用 reflect.Type as the map keys, which you can acquire using reflect.TypeOf()

一个小技巧,如果你想要一个reflect.Type而不必创建一个有问题的类型的值,你可以从那个类型的指针值开始(可能是nil) , 并使用 Type.Elem() 获取指向类型的 reflect.Type 描述符。

例如,要获取结构类型 Point struct{ X, Y int }reflect.Type 描述符而无需实际创建/拥有 Point:

type Point struct{ X, Y int }
tpoint := reflect.TypeOf((*Point)(nil)).Elem()
fmt.Println(tpoint)

打印 main.Point。在 Go Playground.

上试用

查看相关问题: