2016-06-21 60 views
5

Cześć, uczę się Go i robiłem jakieś odbicie. Utknąłem w przypadku tak:Jak mogę dodać elementy do odbicia plastra?

  1. Chcę utworzyć slice z struct przeszedł funkcjonować jako interface{}
  2. Następnie chcę dołączać nowe elementy do tego wycinka

Oto playground z przykładem kodu.

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

Błąd:panic: reflect: call of reflect.Append on interface Value

Czy istnieje sposób, aby to działało? Uwaga: chcę pracować nad referencją.

Rozwiązanie:

Oto co udało mi się zrobić: playground.

+0

Możliwe duplikaty: http://stackoverflow.com/questions/34600817/pointer-to-interface-with-saving-type/34600906 i http://stackoverflow.com/questions/37713749/unmarshal -into-array-of-structs-określona-at-runtime-in-go/37713982 – JimB

Odpowiedz

0

Czy to robi to, co chcesz? (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)) 
} 

Zauważ, że wracam nowy plaster. Myślę, że potrzebujesz kolejnej warstwy pośredniej (wskaźnik do wskaźnika), aby to zrobić bez wartości zwracanej, ale to był mój pierwszy raz, kiedy robiłem odbicie w Go, więc być może wszystko robię źle.

+0

ale chodzi o to, że nie chcę zwracać nowego obiektu, który chcę pracować z referencją, ponieważ wiele pakietów lubię kodować/dekodować json lub sql scan etc itp. – Vardius

+0

@ Vardius: nie zaczynasz od wskaźnika, więc musisz gdzieś zrobić nowy. Przekazanie wskaźnika do interfejsu nie daje ci wskaźnika do twojej wartości. – JimB

+0

@JimB Mam zaktualizowane moje pytanie z moimi dotychczasowymi postępami – Vardius