2016-06-21 11 views
5

Ciao sto imparando Go e stavo facendo un po 'di riflessione. Sono rimasto bloccato in un caso come questo:Come posso aggiungere elementi alla riflessione delle sezioni?

  1. Voglio creare un slice di struct passato di funzionare come interface{}
  2. Poi voglio aggiungere nuovi elementi a questa fetta

ecco un playground con l'esempio di codice.

package main 

import (
    "fmt" 
    "reflect" 
) 

type A struct{ Name string } 

func main() { 
    bbb(A{}) 
} 

func aaa(v interface{}) { 
    sl := reflect.ValueOf(v).Elem() 
    typeOfT := sl.Type() 

    ptr := reflect.New(typeOfT).Interface() 
    s := reflect.ValueOf(ptr).Elem() 
    sl.Set(reflect.Append(sl, s)) 

    ptr = reflect.New(typeOfT).Interface() 
    s = reflect.ValueOf(ptr).Elem() 
    sl.Set(reflect.Append(sl, s)) 
} 

func bbb(v interface{}) { 
    myType := reflect.TypeOf(v) 
    models := reflect.Zero(reflect.SliceOf(myType)).Interface() 
    aaa(&models) 

    fmt.Println(models) 
} 

Errore:panic: reflect: call of reflect.Append on interface Value

C'è un modo per farlo funzionare? Nota: che voglio lavorare su un riferimento.

Soluzione:

Ecco quello che riesco a fare: playground.

+0

possibili duplicati: http://stackoverflow.com/questions/34600817/pointer-to-interface-with-saving-type/34600906 e http://stackoverflow.com/questions/37713749/unmarshal -into-array-of-structs-defined-at-runtime-in-go/37713982 – JimB

risposta

0

Fa questo ciò che vuoi? (playground link)

package main 

import (
    "fmt" 
    "reflect" 
) 

type A struct{ Name string } 

func main() { 
    bbb(A{}) 
} 

func aaa(v interface{}) interface{} { 
    sl := reflect.Indirect(reflect.ValueOf(v)) 
    typeOfT := sl.Type().Elem() 

    ptr := reflect.New(typeOfT).Interface() 
    s := reflect.ValueOf(ptr).Elem() 
    return reflect.Append(sl, s) 
} 

func bbb(v interface{}) { 
    myType := reflect.TypeOf(v) 
    models := reflect.MakeSlice(reflect.SliceOf(myType), 0, 1).Interface() 
    fmt.Println(aaa(models)) 
} 

Si noti che sto tornando alla nuova fetta. Penso che avresti bisogno di un altro livello di riferimento indiretto (puntatore a un puntatore) per farlo senza un valore di ritorno, ma questa è stata la mia prima volta a fare riflessioni su Go, quindi potrei avere delle cose sbagliate.

+0

ma il punto è che non voglio restituire un nuovo oggetto voglio lavorare su un riferimento, come molti pacchetti fanno come json codificare/decodificare o sql scan etc etc – Vardius

+0

@Vardus: non stai iniziando con un puntatore, quindi devi crearne uno nuovo da qualche parte. Passare un puntatore a un'interfaccia non ti dà un puntatore al tuo valore. – JimB

+0

@JimB Ho aggiornato la mia domanda con i miei progressi fino ad ora – Vardius

Problemi correlati