Golang SQL行.泛型类型的所有字段的扫描函数



我想使用sql包中的Scan()函数来执行可能(或不)返回多行的选择语句,并在我的函数中返回这些结果。

I ' m new to Golang泛型,我对如何实现这一点感到困惑。通常,我们会在*sql.Rows上使用Scan函数,并提供对我们希望读取行的预期"结果类型"的所有字段的引用,例如:

var alb Album
rows.Scan(&alb.ID, &alb.Title, &alb.Artist,
&alb.Price, &alb.Quantity)

,其中Album是一个结构类型,显示了这五个字段。

现在,为了不为每个SQL表编写N次类似的函数,我想使用泛型R代替。R是泛型接口类型Result,我将此类型定义为N个不同结构体中的一个:
type Result interface {
StructA | StructB | StructC
}
func ExecSelect[R Result](conn *sql.DB, cmd Command, template R) []R

我怎么能现在写rows.Scan(...)应用扫描操作对我的结构的R的具体类型的所有字段?例如,我想有rows.Scan(&res.Field1, &res.Field2, ...)的res是R类型,扫描应该接收我当前的具体类型R的所有字段。我是否真的需要提供一个"模板"作为R的具体类型的参数,以便在运行时它变得清晰哪个结构现在是相关的?

请纠正我在考虑泛型时所犯的任何错误。

这是一个糟糕的泛型用例。

函数sql.Rows.Scan的参数应该是扫描目的地,即你的结构字段,结果集中每列一个,在泛型函数体内,你不能访问R类型参数的字段。

即使你这样做,在你的Result约束结构可能有不同的字段…?那么你如何设想写泛型不同的一起工作的代码字段?

您可以通过提供任意结构体扫描(如sqlx)和StructScan等功能的包来完成您想要的功能,但是它在底层使用反射将结构体字段映射到sql.Rows.Scan参数,因此使用泛型根本没有获得任何好处。

如果有的话,你正在使它变得更糟,因为现在你有了使用类型参数的额外性能开销。

最新更新