2012-04-18 15 views
14

¿Alguien puede decirme cómo crear una nueva instancia de Tipo a partir de una cadena? ¿Reflejar?Instancia nuevo Tipo (Golang)

hay ejemplos pero son de las más antiguas (anteriores versiones Go 1) de la lengua [:(]

+2

Por favor, aclarar un poco su pregunta, no es claro para mí. También parece incompleto después de la final '('. – zzzz

Respuesta

29

Por lo tanto, si entiendo bien su pregunta, usted está preguntando acerca de cómo se puede crear un objeto cuando simplemente tiene el nombre del tipo como cadena. Entonces, por ejemplo, podría tener una cadena "MyStruct" y desea crear un objeto de este tipo.

Desafortunadamente, eso no es posible porque Go es estáticamente el lenguaje mecanografiado y el enlazador eliminará el código muerto (o partes en línea). Por lo tanto, no hay garantía de que el ejecutable final incluso contenga el código de "MyStruct".

Sin embargo, puede mantener un map[string]reflect.Type global manualmente. Por ejemplo, al inicializar este mapa en la función init() de sus paquetes, que define dichos tipos descubribles. Esto también le dirá al compilador que está usando los tipos. Después, puede usar este mapa para buscar el reflect.Type del tipo que desea crear y usar reflect.New para obtener un puntero a un nuevo objeto de ese tipo (almacenado como un valor de reflect.Value). Puede extraer el objeto en una interfaz con algo como esto:

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

Elem() se de-reference el puntero y Interface() devolverá el valor reflejado como un interface{}. Ver The Laws of Reflection para más detalles.

PD: Puede haber una mejor forma de estructurar su programa que ni siquiera requiere reflexión y que permite al compilador detectar más errores. ¿Ha considerado usar un factory method por ejemplo? Otra solución fácil podría ser mantener un map[string]func() interface{} de funciones que se pueden invocar para crear un nuevo objeto con ese nombre.

+2

¿Cómo implementaría un método de fábrica dentro de Go? –

5

de fábrica con los constructores predefinidos puede basarse en algo así como:

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()) 
    } 
} 
Cuestiones relacionadas