扫描不工作

Scan not working

我的扫描没有更新它的目标变量。我有点让它工作:

ValueName := reflect.New(reflect.ValueOf(value).Elem().Type())

但我不认为它按照我想要的方式工作。

func (self LightweightQuery) Execute(incrementedValue interface{}) {
    existingObj := reflect.New(reflect.ValueOf(incrementedValue).Elem().Type())
    if session, err := connection.GetRandomSession(); err != nil {
        panic(err)
    } else {
        // buildSelect just generates a select query, I have test the query and it comes back with results.
        query := session.Query(self.buildSelect(incrementedValue))
        bindQuery := cqlr.BindQuery(query)
        logger.Error("Existing obj ", existingObj)
        for bindQuery.Scan(&existingObj) {
            logger.Error("Existing obj ", existingObj)
            ....
        }
   }
}

两条日志信息完全一样Existing obj &{ 0 0 0 0 0 0 0 0 0 0 0 0}(空格是字符串字段。)这是因为大量使用反射生成新对象吗?在他们的文档中,它说我应该使用 var ValueName type 来定义我的目的地,但我似乎无法通过反思来做到这一点。我意识到这可能很愚蠢,但也许只是为我指出进一步调试的方向会很棒。我的围棋技术很差!

你到底想要什么?您要更新传递给 Execute() 的变量吗?

如果是这样,您必须将指针传递给 Execute()。然后你只需要将 reflect.ValueOf(incrementedValue).Interface() 传递给 Scan()。这是有效的,因为 reflect.ValueOf(incrementedValue) 是一个 reflect.Value holding an interface{} (the type of your parameter) which holds a pointer (the pointer you pass to Execute()), and Value.Interface() 将 return 一个 interface{} 类型的值持有指针,你必须传递的确切内容 Scan().

查看此示例(使用 fmt.Sscanf(),但概念相同):

func main() {
    i := 0
    Execute(&i)
    fmt.Println(i)
}

func Execute(i interface{}) {
    fmt.Sscanf("1", "%d", reflect.ValueOf(i).Interface())
}

它将从 main() 打印 1,因为值 1 设置在 Execute().

如果您不想更新传递给 Execute() 的变量,只需创建一个具有相同类型的新值,因为您使用的是 reflect.New(),而 return Value 的指针,你必须传递 existingObj.Interface() 其中 return 是一个 interface{} 持有指针,你想传递给 Scan() 的东西。 (你所做的是将指向 reflect.Value 的指针传递给 Scan(),这不是 Scan() 所期望的。)

演示fmt.Sscanf()

func main() {
    i := 0
    Execute2(&i)
}

func Execute2(i interface{}) {
    o := reflect.New(reflect.ValueOf(i).Elem().Type())
    fmt.Sscanf("2", "%d", o.Interface())
    fmt.Println(o.Elem().Interface())
}

这将打印 2

Execute2() 的另一个变体是,如果您在 reflect.New() 编辑的值 return 上调用 Interface()

func Execute3(i interface{}) {
    o := reflect.New(reflect.ValueOf(i).Elem().Type()).Interface()
    fmt.Sscanf("3", "%d", o)
    fmt.Println(*(o.(*int))) // type assertion to extract pointer for printing purposes
}

这个 Execute3() 将按预期打印 3

尝试 Go Playground 上的所有示例。