【问题标题】:Fill a slice with field pointers of a struct用结构的字段指针填充切片
【发布时间】: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 就是这样,谢谢!

标签: go struct slice


【解决方案1】:

根据 mkopriva 对该问题的评论,使用以下内容获取该字段的地址:

for i := 0; i < countColumns; i++ {
   columnsPointers[i] = val.Field(i).Addr().Interface()
}

【讨论】:

    猜你喜欢
    • 2015-02-21
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    • 2015-07-04
    • 2013-02-26
    • 2019-12-19
    相关资源
    最近更新 更多