【发布时间】:2019-11-10 16:14:26
【问题描述】:
我正在创建一个接收interface{} 的函数,它始终是一个结构,但它可以是任何结构。
我需要用接收到的结构的所有字段的指针填充一个切片。下面代码中我需要选择字段指针的位置标记为**FIELD POINTER**
我的最终目标是创建一个函数来接收一个 struct,该函数与在参数 sqlQuery 中发送的查询的返回等效。我想创建一个动态函数来执行任何类型的查询以进行选择,始终使用为.Scan 收到的结构。
可能是我想错了,我还在开始Golang。
func QuerySelect(entity interface{}, sqlQuery string) {
val := reflect.Indirect(reflect.ValueOf(entity))
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
"password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
// Validate database params
db, err := sql.Open(driver, psqlInfo)
// If returned any error
if err != nil {
panic(err)
}
// Validate connection with database
err = db.Ping()
if err != nil {
panic(err)
}
// Execute query
rows, err := db.Query(sqlQuery)
countColumns := val.Type().NumField()
var allRows []interface{}
for rows.Next() {
columnsPointers := make([]interface{}, countColumns)
for i := 0; i < countColumns; i++ {
columnsPointers[i] = **FIELD POINTER (entity struct)**
}
if err := rows.Scan(columnsPointers...); err != nil {
log.Fatal(err)
}
allRows = append(allRows, entity)
}
}
【问题讨论】:
-
play.golang.com/p/CCzvpnZSOLQ 这是你要找的吗?
-
@mkopriva 所以,我刚才尝试使用
.Addr(),但是.Scan()不接受您的退货。它返回以下错误:sql: Scan error on column index 0: destination not a pointer -
我的错,
Addr仍然将该指针包装在reflect.Value中并返回它,因此要使其成为扫描的有效参数,您需要“解包”它,即获取包含在reflect.Value,为此你可以调用Interface方法。即val.Field(i).Addr().Interface() -
@mkopriva 就是这样,谢谢!