扫描不起作用



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

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保存一个interface{}(参数的类型(,该保存一个指针(您传递给Execute()的指针(,并且Value.Interface()将返回一个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()的变量,只需创建一个具有相同类型的新值,因为您使用的是返回指针Valuereflect.New(),因此您必须传递existingObj.Interface()返回一个持有指针的interface{},即您要传递给Scan()的东西。(你所做的是你传递了一个指向Scan() reflect.Value的指针,这不是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() 返回的值调用 Interface() right:

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上的所有示例。

最新更新