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

98 views Asked by At

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 clarify my goal (following '@Muffin Top' and '@Volker' answer), I currently do this registration manualy into a pointer store present in each package. There are two problems with this approach, the registration is a mundane task and it is error prone.

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
}

For the solution, I know there is no such function in the reflect standard library or any other library I know of. However, I was contemplating :

  • an algorithm that parses the entire program memory, identify each variable, get its type and gather those that match the struct type of the package. Since delve and heapdump do parse the entire memory and that delve can guess the variable type, I have a hunch that my desired function could be implemented. I have been trying to see how delve is doing or how heapcoredump is developped but this is a too big piece of knowledge to swallow for the desired goal.

  • an alternative would be to add a pre-compilation step that modifies the abstract syntax tree (AST) by adding the registration each time there is a a variable initialisation.

  • 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 or the entire memory could be parsed.

1

There are 1 answers

9
Volker On

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

No.

You must redesign, e.g. by allocating the instances through a function which memorizes them.