Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you get a reflect.Type instance of an struct without physically creating the struct?

I want to create a registry of struct types to enable dynamic loading of solutions to 'Project Euler' problems. My current solution however requires the struct to first be created and zeroed before it's type can be registered:

package solution

import (
    "errors"
    "fmt"
    "os"
    "reflect"
)

type Solution interface {
    Load()
    Solve() string
}

type SolutionRegister map[string]reflect.Type

func (sr SolutionRegister) Set(t reflect.Type) {
    fmt.Printf("Registering %s\n", t.Name())
    sr[t.Name()] = t
}

func (sr SolutionRegister) Get(name string) (Solution, error) {
    if typ, ok := sr[name]; ok {
        sol := reflect.New(typ).Interface().(Solution)
        return sol, nil
    }
    return nil, errors.New("Invalid solution: " + name)
}

var solutionsRegistry = make(SolutionRegister)

func Register(sol Solution) {
    solutionsRegistry.Set(reflect.TypeOf(sol).Elem())
}

func Load(s string) Solution {
    sol, err := solutionsRegistry.Get(s)
    if err != nil {
        fmt.Printf("Error loading solution  %s (%s)\n", s, err)
        os.Exit(-1)
    }
    sol.Load()
    return sol
}

type DummySolution struct {
    data [100 * 1024 * 1024 * 1024]uint8
}

func (s *DummySolution) Load() {
}

func (s *DummySolution) Solve() string {
    return ""
}

func Init() {
    Register(&DummySolution{})
}

In this example the type of 'DummySolution struct' is registered inside the Init() function. This structure is purposefully absurdly large to illustrate the problem.

Is there a way I could access the type of DummySolution and other Solutions without having to create an instance of the structure beforehand?

like image 295
Jansen du Plessis Avatar asked Oct 29 '25 13:10

Jansen du Plessis


1 Answers

You can use reflect.TypeOf((*DummySolution)(nil)).Elem(). Making a nil pointer doesn't allocate space for the whole struct, and Elem (described under the definition of reflect.Type) gets you from a pointer (or slice, array, channel, or map) to its element type.

like image 146
twotwotwo Avatar answered Oct 31 '25 09:10

twotwotwo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!