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

huangapple go评论82阅读模式
英文:

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

问题

我想创建一个结构类型的注册表,以便动态加载解决“Project Euler”问题的解决方案。然而,我的当前解决方案要求在注册类型之前必须先创建并清零结构:

在这个例子中,'DummySolution struct'的类型在Init()函数中注册。这个结构故意设置得非常大,以说明问题。

有没有一种方法可以在不事先创建结构实例的情况下访问DummySolution和其他解决方案的类型?

英文:

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?

答案1

得分: 5

你可以使用reflect.TypeOf((*DummySolution)(nil)).Elem()。创建一个nil指针不会为整个结构体分配空间,而Elem(在reflect.Type的定义下描述)可以将指针(或切片、数组、通道或映射)转换为其元素类型。

英文:

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.

huangapple
  • 本文由 发表于 2016年2月3日 07:12:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/35165615.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定