Eug*_*sky 5 dictionary key go hashable go-gorm
我想创建一组在我的应用程序中使用的 gorm 类型。所以我想map用我的类型定义 agorm.DB作为键,空structs{}作为标志:
var (
autoMigrations map[gorm.DB]struct{}
)
Run Code Online (Sandbox Code Playgroud)
但是编译器不允许我用错误来做这个:invalid map key type gorm.DB. 我可以使用指向gorm.DBs 的指针来愚弄它,例如:
map[*gorm.DB]struct{}
Run Code Online (Sandbox Code Playgroud)
但这不是解决方案,因为我需要使它独一无二,如果我的地图被填满,db.AutoMigrate(&Chat{})我可以获得许多具有不同地址的类似对象。
另一种解决方案是制作一片gorm.DB:
autoMigrations []gorm.DB
Run Code Online (Sandbox Code Playgroud)
但是我必须手动过滤元素,这似乎有点疯狂。
该比较操作符==和=必须为键类型的操作数被完全定义!; 因此键类型不能是函数、映射或切片。
gorm.DB 是一个结构体,并且结构体值只有在它们的所有字段都具有可比性时才具有可比性:
如果所有字段都具有可比性,则结构值具有可比性。如果它们对应的非空白字段相等,则两个结构值相等。
但是gorm.DB有一个例如DB.values地图类型的字段,并且地图是不可比较的,因此gorm.DB值也不可比较,因此您不能将其用作地图键。
如果要创建一组类型,则应将其reflect.Type用作映射键,您可以reflect.TypeOf()从该类型的值中获取这些键。
一个小技巧,如果您想要 areflect.Type而不必创建相关类型的值,您可以从该类型的指针值(可能是nil)开始,并使用它Type.Elem()来获取reflect.Type所指向类型的描述符。
例如,要获取reflect.Type结构类型的描述符Point struct{ X, Y int }而不实际创建/具有Point:
type Point struct{ X, Y int }
tpoint := reflect.TypeOf((*Point)(nil)).Elem()
fmt.Println(tpoint)
Run Code Online (Sandbox Code Playgroud)
哪个打印main.Point。在Go Playground上试一试。
查看相关问题:
为什么 Go slice 不能用作 Go 映射中的键,就像数组可以用作键一样?