Экземпляр нового Типа (Голанг)

go types instance go-reflect

18187 просмотра

2 ответа

Может кто-нибудь сказать мне, как создать новый экземпляр типа из строки? Задумайтесь?

Есть примеры, но они для более старого (до Go 1 версии) языка [:(]

Автор: Accex Источник Размещён: 12.11.2019 09:42

Ответы (2)


31 плюса

Решение

Итак, если я правильно понимаю ваш вопрос, вы спрашиваете, как вы можете создать объект, когда у вас просто есть имя типа в виде строки. Так, например, у вас может быть строка «MyStruct», и вы хотите создать объект этого типа.

К сожалению, это нелегко сделать, потому что Go является языком статической типизации, и компоновщик удалит мертвый код (или его встроенные части). Таким образом, нет никакой гарантии, что ваш конечный исполняемый файл будет даже содержать код «MyStruct».

Вы можете, однако, поддерживать глобальный map[string]reflect.Typeвручную. Например, инициализируя эту карту в init()функции ваших пакетов, которая определяет такие обнаруживаемые типы. Это также скажет компилятору, что вы используете типы. После этого вы можете использовать эту карту, чтобы найти refle.Type типа, который вы хотите создать, и использовать refle.New, чтобы получить указатель на новый объект этого типа (сохраненный как refle.Value). Вы можете извлечь объект в интерфейс с чем-то вроде этого:

reflect.New(yourtype).Elem().Interface()

Elem () отменяет указатель, а Interface () возвращает отраженное значение как interface{}. См . Законы Отражения для получения дополнительной информации.

PS: может быть лучший способ структурировать вашу программу, который даже не требует отражения и который позволяет компилятору ловить больше ошибок. Рассматривали ли вы, например, использование заводского метода ? Другим простым решением может быть сохранение map[string]func() interface{}функций, которые можно вызывать для создания нового объекта с таким именем.

Автор: tux21b Размещён: 18.04.2012 02:47

6 плюса

Фабрика с предопределенными конструкторами может быть основана на чем-то вроде:

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())
    }
}
Автор: Mirek Rusin Размещён: 10.12.2013 01:17
Вопросы из категории :
32x32