英文:
StructScan unknown struct slice [GO]
问题
所以,我想通过StructScan
方法填充任何结构体,并将从数据库中获取的任何数据读入相应的结构体中,然后将其提供给测试函数。
如果你实现了其他的东西,比如数据库连接等,这个脚本就不会出现编译错误,但是StructScan
方法仍然会返回一个错误,并告诉我它期望一个结构体的切片。
我如何创建一个我不知道类型的结构体切片?
谢谢任何建议。
package main
import (
"database/sql"
"github.com/jmoiron/sqlx"
)
var db *sql.DB
type A struct {
Name string `db:"name"`
}
type B struct {
Name string `db:"name"`
}
func main() {
testA := []A{}
testB := []B{}
test(testA, "StructA")
test(testB, "StructB")
}
func test(dataStruct interface{}, name string) {
rows, err := db.Query("SELECT * FROM table WHERE name =", name)
if err != nil {
panic(err)
}
for rows.Next() {
err := sqlx.StructScan(rows, &dataStruct)
if err != nil {
panic(err)
}
}
}
英文:
So I would like to fill any struct via the StructScan
method and so read any data I get from the db into the regarding struct I feed the test function.
This script doesn't give any compile error (if you implement the other stuff like a db connection and so on) but still the StructScan
method returns an error and tells me that it expects a slice of structs.
How do I create a slice of structs that I don't know the type of?
Thanks for any advice.
package main
import (
"database/sql"
"github.com/jmoiron/sqlx"
)
var db *sql.DB
type A struct {
Name string `db:"name"`
}
type B struct {
Name string `db:"name"
}
func main() {
testA := []A{}
testB := []B{}
test(testA, "StructA")
test(testB, "StructB")
}
func test(dataStruct interface{}, name string) {
rows, err := db.Query("SELECT * FROM table WHERE name =", name)
if err != nil {
panic(err)
}
for rows.Next() {
err := sqlx.StructScan(rows, &dataStruct)
if err != nil {
panic(err)
}
}
}
答案1
得分: 2
非常晚才参与讨论,但在研究另一个问题时遇到了这个问题。对于其他遇到这个问题的人来说,问题在于你将指针传递给了dataStruct
到StructScan()
函数。dataStruct
是一个接口,而在Go语言中,几乎总是将接口指针传递给函数是错误的(实际上,几个版本前他们移除了对接口指针的自动解引用)。你还通过值传递了你的目标。
所以,你传递了一个指向接口的指针,该接口保存了你目标切片的副本,而你实际上想要的是直接传递接口,并且该接口保存指向你目标切片的指针。
不要使用:
test(testA, "StructA")
test(testB, "StructB")
// ...
err := sqlx.StructScan(rows, &dataStruct)
而要使用:
test(&testA, "StructA")
test(&testB, "StructB")
// ...
err := sqlx.StructScan(rows, dataStruct)
英文:
Super late to the party, but ran into this question while researching another issue. For others that stumble upon it, the problem is that you're passing a pointer to dataStruct
into StructScan()
. dataStruct
is an interface, and pointers to interfaces are almost always an error in Go (in fact, they removed the automatic dereferencing of interface pointers a few versions back). You're also passing in your destination by value.
So, you are passing a pointer to an interface that holds a copy of your destination slice, when what you want instead is to pass the interface directly, and that interface to hold a pointer to your destination slice.
Instead of:
test(testA, "StructA")
test(testB, "StructB")
// ...
err := sqlx.StructScan(rows, &dataStruct)
Use:
test(&testA, "StructA")
test(&testB, "StructB")
// ...
err := sqlx.StructScan(rows, dataStruct)
答案2
得分: 0
如果你不知道目标结构类型是什么,可以使用sqlx.MapScan
或sqlx.SliceScan
。它们不会映射到结构体,但会返回查询结果中的所有列。
请参考http://jmoiron.github.io/sqlx/#altScanning。
英文:
If you have no idea what the destination struct type is, use sqlx.MapScan
or sqlx.SliceScan
. They don't map to a struct, but both return all the columns from the query result.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论