構造体タイプのレジストリを作成して、「プロジェクトオイラー」問題のソリューションの動的ロードを有効にします。ただし、現在のソリューションでは、構造体を作成してゼロにしてから、タイプを登録する必要があります。
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{})
}
この例では、「DummySolution構造体」のタイプがInit()関数内に登録されています。この構造は、問題を説明するために意図的に不条理に大きくなっています。
構造体のインスタンスを事前に作成せずに、DummySolutionや他のソリューションのタイプにアクセスできる方法はありますか?
使用できますreflect.TypeOf((*DummySolution)(nil)).Elem()
。nil
ポインタを作成しても、構造体全体にスペースが割り当てられるわけではなく、Elem
(の定義で説明されているreflect.Type
)ポインタ(またはスライス、配列、チャネル、マップ)からその要素型に移動します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加