扫描不工作

时间:2016-02-05 05:00:44

标签: go gocql cqlr

我的扫描未更新其目标变量。我有点合作:

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来定义我的目的地,但我似乎无法通过反射来做到这一点。我意识到这可能是愚蠢的,但也许只是指着我进一步调试的方向这将是伟大的。我对Go的技巧非常缺乏!

1 个答案:

答案 0 :(得分:1)

你想要的是什么?是否要更新传递给Execute()的变量?

如果是这样,您必须将指针传递给Execute()。然后,您只需将reflect.ValueOf(incrementedValue).Interface()传递给Scan()。这是有效的,因为reflect.ValueOf(incrementedValue)reflect.Value持有interface{}(您的参数的类型),它包含一个指针(您传递给Execute()的指针),以及{{3 }}将返回一个包含指针的interface{}类型的值,这是您必须传递Scan()的确切内容。

请参阅此示例(使用Value.Interface(),但概念相同):

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

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

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

如果您不想更新传递给Execute()的变量,只需创建一个类型相同的新值,因为您正在使用reflect.New()返回{{1}一个指针,你必须传递Value,它返回一个持有指针的existingObj.Interface(),你要传递给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()返回的值上调用Interface()

reflect.New()

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()

尝试 fmt.Sscanf() 上的所有示例。