2016-06-21 8 views
5

Hallo ich lerne Go und ich machte einige Überlegungen. Ich habe in einem Fall wie diesem stecken:Wie kann ich der Spiegelreflexion Elemente hinzufügen?

  1. ich ein slice von struct weitergegeben erstellen möchten, um als interface{}
  2. Dann möchte ich neue Elemente dieser Scheibe

Hier anhängen ist ein playground mit dem Codebeispiel.

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

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

Gibt es eine Möglichkeit, es funktioniert? Hinweis: Ich möchte an einer Referenz arbeiten.

Lösung:

Hier ist, was ich tun verwalten zu: playground.

+0

Mögliche Duplikate: http://stackoverflow.com/questions/34600817/pointer-to-interface-with-saving-type/34600906 und http://stackoverflow.com/questions/37713749/unmarshal -into-array-of-structs-determined-at-runtime-in-go/37713982 – JimB

Antwort

0

Macht das, was Sie wollen? (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)) 
} 

Bitte beachte, dass ich die neue Scheibe bin zurück. Ich denke, dass Sie eine andere Indirektionsebene (Zeiger auf einen Zeiger) benötigen würden, um dies ohne einen Rückgabewert zu tun, aber dies war das erste Mal, dass ich in Go reflektierte, also könnte ich Dinge falsch machen.

+0

aber der Punkt ist, ich möchte nicht ein neues Objekt zurückgeben, ich möchte auf eine Referenz arbeiten, wie viele Pakete wie JSON encode/decode oder sql scan etc etc – Vardius

+0

@Vardius: Sie beginnen nicht mit einem Zeiger, so müssen Sie irgendwo einen neuen machen. Wenn Sie einen Zeiger auf eine Schnittstelle übergeben, erhalten Sie keinen Zeiger auf Ihren Wert. – JimB

+0

@JimB Ich habe meine Frage mit meinem Fortschritt so weit aktualisiert – Vardius

Verwandte Themen