database - 如何从 interface{} 值(反射)为显式类型的结构成员设置新值?戈朗

标签 database reflection interface go

我想了解使用反射包的一些微妙时刻。请看下面的示例,它更好地描述了我想知道的内容:

type Robot struct {
    id    int
    model string
}

func change(i interface{}, fields ...string) {
        v := reflect.ValueOf(i).Elem()
        // here I emulate function by slice that could return any value,
        // so here I need to check if I can store incoming values to existing struct
        returns := []interface{}{100, "Something"}
        for i, name := range fields {
            x := reflect.ValueOf(&returns[i]).Elem()
            //check if value representing x is the same of struct member
            v.FieldByName(name).Set(x)
            // ^ here I want to store 100 to Robot.id when i = 0,
            // and "Something" to Robot.model when i = 1
        }


}

func main() {
    robot := &Robot{id: 1, model: "T310"}
    change(robot, "model", "id")
    // now robot become as follows: &Robot{100, "Something"}
}

为什么需要它?

    // It is need for retrieving values from sql DB into struct members 
    // (only for training purposes :))
    // Example:
    f := func(q string, structs interface{}, fields ...string) {
        rows, _ := db.Query(q)
        for i := 0; rows.Next(); i++ {
            rows.Scan(&structs[i])
            // very dirty here! it's hard to understand how to implement it
        }
    }
    var robots = []*Robot
    f("select id, model from robots", robots, "id", "model")
    // now each member of robots var should contain values from DB

我试图尽可能简短地进行描述和解释。我希望你理解我..

最佳答案

您只能通过反射设置导出字段,因此请先将其大写。否则,如果您指望位置值,请确保它们正确对齐。

例如:http://play.golang.org/p/ItnjwwJnxe

type Robot struct {
    ID    int
    Model string
}

func change(i interface{}, fields ...string) {
    returns := []interface{}{100, "Something"}

    v := reflect.ValueOf(i).Elem()
    for i, name := range fields {
        val := reflect.ValueOf(returns[i])
        v.FieldByName(name).Set(val)
    }
}

func main() {
    robot := &Robot{ID: 1, Model: "T310"}
    fmt.Println(robot)
    change(robot, "ID", "Model")
    fmt.Println(robot)
}

关于database - 如何从 interface{} 值(反射)为显式类型的结构成员设置新值?戈朗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27990522/

相关文章:

java - 将 Generic 与 Class<?> 参数一起使用时出错

go - 如何设计一个返回另一个只能紧急实现的接口(interface)类型的接口(interface)

go - 试图将文字转换为 Golang 中的指针

c# - 泛型类型的转换无效

更新json的数据库函数

php - 这个问题应该如何设计数据库结构呢?

sql - 在不知道父行是什么的情况下,删除父行时删除子行的最简单方法是什么?

MySQL-Oracle桥接

c# - 为什么反射搜索会突然找不到任何东西?

java - 使用匹配的正则表达式调用子类的方法