1

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

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来定义我的目的地,但我似乎无法通过反射来做到这一点。我意识到这可能很愚蠢,但甚至可能只是为我指明进一步调试的方向,这会很棒。我的围棋技巧相当欠缺!

4

1 回答 1

1

你到底想要什么?你想更新你传递给的变量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())
}

它将1从打印main(),因为值1是在里面设置的Execute()

如果您不想更新传递给的变量Execute(),只需创建一个具有相同类型的新值,因为您使用reflect.New()的是返回Value指针的,您必须通过existingObj.Interface()返回interface{}持有指针的指针,您想要的东西传给Scan(). (您所做的是传递了一个指向 a 的指针,reflect.ValueScan()不是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()对返回的值调用 right 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()打印。3

尝试Go Playground上的所有示例。

于 2016-02-05T07:36:23.203 回答