StructScan 未知的结构切片 [GO]

huangapple go评论80阅读模式
英文:

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

非常晚才参与讨论,但在研究另一个问题时遇到了这个问题。对于其他遇到这个问题的人来说,问题在于你将指针传递给了dataStructStructScan()函数。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.MapScansqlx.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.

See http://jmoiron.github.io/sqlx/#altScanning

huangapple
  • 本文由 发表于 2015年12月16日 22:20:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/34314429.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定