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

に渡された変数を更新したくない場合はExecute()、同じ型の新しい値を作成するだけです。ポインターのreflect.New()戻り値を使用しているため、ポインターを保持している戻り値Valueを渡す必要があります。に渡します。(あなたがしたことは、何かが期待されていないへのポインタを渡したということです。)existingObj.Interface()interface{}Scan()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

の別のバリアントは、によって返された値に対して rightExecute2()を呼び出す場合です。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()は期待どおりに印刷3されます。

Go Playgroundですべての例を試してください。

于 2016-02-05T07:36:23.203 に答える