Может ли кто-нибудь сказать мне, как создать новый экземпляр типа из строки? Задумайтесь?
Есть примеры, но они предназначены для более старых (pre Go 1 версий) языка [: (]
Может ли кто-нибудь сказать мне, как создать новый экземпляр типа из строки? Задумайтесь?
Есть примеры, но они предназначены для более старых (pre Go 1 версий) языка [: (]
Итак, если я правильно понял ваш вопрос, вы спрашиваете о том, как создать объект, когда у вас просто есть имя типа в виде строки. Так, например, у вас может быть строка "MyStruct", и вы хотите создать объект этого типа.
К сожалению, это не так легко, потому что Go является статически типизированным языком, и компоновщик удалит мертвый код (или его внутренние части). Таким образом, нет никакой гарантии, что ваш окончательный исполняемый файл будет содержать код "MyStruct".
Однако вы можете поддерживать глобальный map[string]reflect.Type
вручную. Например, инициализируя эту карту в функции init()
ваших пакетов, которая определяет такие типы обнаружения. Это также скажет компилятору, что вы используете типы. Впоследствии вы можете использовать эту карту, чтобы найти reflect.Type типа, который вы хотите создать, и использовать отразить. Новое, чтобы получить указатель на новый объект этого типа (сохраненный как отражение .Value). Вы можете извлечь объект в интерфейс с чем-то вроде этого:
reflect.New(yourtype).Elem().Interface()
Elem() отключит ссылку на указатель и Interface() вернет отраженное значение как interface{}
. Подробнее см. Законы отражения.
PS: Может быть, лучший способ структурировать вашу программу, которая даже не требует отражения, и которая позволяет компилятору уловить больше ошибок. Рассматривали ли вы, например, метод factory? Другим простым решением может быть поддержка map[string]func() interface{}
функций, которые могут быть вызваны для создания нового объекта с этим именем.
Factory с предопределенными конструкторами может быть основан на следующем:
package main
import (
"fmt"
)
type Creator func() interface{}
type A struct {
a int
}
type B struct {
a bool
}
func NewA() interface{} {
return new(A)
}
func NewB() interface{} {
return new(B)
}
func main() {
m := map[string]Creator{}
m["A"] = NewA
m["B"] = NewB
for k, v := range m {
fmt.Printf("%v -> %v\n", k, v())
}
}