泛型结构实现与泛型接口不匹配



我正在尝试go泛型,并且遇到了这个问题。为什么Schedule不匹配any?

func demo(m Model[any]) Model[any] {
return m
}
type Model[M any] interface {
FindOne(db *gorm.DB, conds ...any) (m M)
}
type DbOperations[M any] struct{}
func (d DbOperations[M]) FindOne(db *gorm.DB, conds ...any) (m M) {
res := db.First(&m, conds)
if res.Error != nil {
return m
}
return m
}

// the program does not compile because of this function
func a() {
m := DbOperations[Schedule]{}
get(m) // <= error occurs here
}
错误消息

../models/operations.go:103:6: cannot use m (variable of type DbOperations[Schedule]) as type Model[any] in argument to get:
DbOperations[Schedule] does not implement Model[any] (wrong type for FindOne method)
have FindOne(db *gorm.DB, conds ...any) (m Schedule)
want FindOne(db *gorm.DB, conds ...any) any

go语言通常要求您明确使用的类型,并且通常不会自动为您强制转换变量。所以这行不通,因为Model[any](又名Model[interface{}])和Model[Schedule]不是同一种类型。(下面有更多细节)

你可以做的是,让get成为一个泛型函数:

func get[T any](m Model[T]) Model[T] {
return m
}

,然后在调用函数时指明类型:

func a() {
m := DbOperations[Schedule]{}
get[Schedule](m)
}

详细信息Model[any] != Model[SomeType]的原因与不能将字符串切片传递给接受any切片参数的函数的原因相同:

[]interface{}片与[]Schedule片具有不同的内存布局。类似地,Model[T]在内存中的布局与Model[any]不同。Go期望您完成转换它们的工作。(在这里总结官方解释和SO答案)

最新更新