samedi 3 octobre 2020

Is there a way in go to dynamicaly gather instances of a given struct type?

I would like, at any stage in a program, to perform an operation on all instances of a struct defined in a given package. In order to do that, I have contemplated developping a function that gather those instances. But I haven't found anything yet.

To make my case clear, consider a package foo with one struct Foo. Foo has one string field Name. The package also defines two instances of Foo declared as Foo1 & Foo2

package foo

type Foo struct {
    Name string
}

var Foo1, Foo2 = Foo{Name: "Foo1"}, Foo{Name: "Foo2"}

The GetInstancesOfPkg I am trying to implement would be called like in the below example. The operation to perform is just to print the Name field.

This is a working example but with a mockup version of GetInstancesOfPkg.

package main

import (
    "log"
    "reflect"

    "github.com/thomaspeugeot/test-heapdump/foo"
)

func main() {

    s := GetInstancesOfPkg("github.com/thomaspeugeot/test-heapdump/foo")

    for _, instance := range s {
        // cast instance on foo.Foo
        if f, ok := instance.(*foo.Foo); !ok {
            log.Panic("Unknown Struct " + reflect.TypeOf(instance).Name())
        } else {
            log.Printf("Instance of Foo has name %s ", f.Name)
        }
    }
}

// GetInstancesOfPkg return a slice of instances of Struct defined in the package pkgPath
// --- this is the mockup verion ---
func GetInstancesOfPkg(pkgPath string) (interfaceSlice []interface{}) {

    var listOfFooInstances = []*foo.Foo{&foo.Foo1, &foo.Foo2}

    interfaceSlice = make([]interface{}, len(listOfFooInstances))
    for i, d := range listOfFooInstances {
        interfaceSlice[i] = d
    }
    return
}
  • I have been trying to see how delve is doing or how heapcoredump is developped but this seems a too big piece of knowledge to swallow
  • I am not even sure if this level of reflexion is possible with go (or if it is portable ?)
  • Performance is not an issue, the program could be compiled with wathever flag necessary




Aucun commentaire:

Enregistrer un commentaire