valor una subyacentes subyacente que mercado instrumento financieros ejemplos ejemplo derivados derivado clasificacion activos activo accion reflection go

reflection - una - mercado de derivados ejemplos



¿Cómo obtener valor subyacente de un reflejo.Valor en golang? (3)

Así que encontré un código que me ayudó a comenzar con la reflexión en Go (golang), pero tengo problemas para obtener el valor subyacente, por lo que básicamente puedo crear una map[string]string de una estructura y sus campos.

Finalmente, me gustaría convertir el resultado en una map[string]interface{} , pero este único problema me está bloqueando.

El código que tengo en este momento:

package main import ( "fmt" "reflect" ) type Foo struct { FirstName string `tag_name:"tag 1"` LastName string `tag_name:"tag 2"` Age int `tag_name:"tag 3"` } func inspect(f interface{}) map[string]string { m := make(map[string]string) val := reflect.ValueOf(f).Elem() for i := 0; i < val.NumField(); i++ { valueField := val.Field(i) typeField := val.Type().Field(i) f := valueField.Interface() val := reflect.ValueOf(f) m[typeField.Name] = val.String() } return m } func dump(m map[string]string) { for k, v := range m { fmt.Printf("%s : %s/n", k, v) } } func main() { f := &Foo{ FirstName: "Drew", LastName: "Olson", Age: 30, } a := inspect(f) dump(a) }

La salida de ejecutar el código:

FirstName : Drew LastName : Olson Age : <int Value>

Por lo que entiendo, la salida para FirstName y LastName son objetos reflect.Value reales, pero para las cadenas, el método String () en el valor solo genera la cadena subyacente. Me gustaría obtener el int y cambiarlo en una cadena, pero de la documentación del paquete de relfect no veo de inmediato cómo se hace.

Soo .... ¿Cómo obtengo el valor subyacente de un reflejo.Valor en golang?


Esto debería ser más fácil de hacer con Go 1.5 (agosto de 2015) Ver la revisión 8731 y confirmar 049b89d por Rob Pike ( robpike ) :

fmt : treat reflect.Value especialmente - como el valor que tiene

Esto le permitiría imprimir el valor real de un argumento Reflect.Value() :

Cuando se pasa un valor reflect.Value a Printf (etc.), fmt llama método String , que no revela su contenido.
Para obtener el contenido, se podría llamar a Value.Interface() , pero eso es ilegal si el Value no se exporta o está prohibido.

Este CL mejora la situación con un cambio trivial en el paquete fmt : cuando vemos un reflect.Value como un argumento, lo tratamos exactamente como tratamos un reflect.Value lo hacemos dentro del paquete.
Esto significa que siempre imprimimos el contenido del Value como si ese fuera el argumento de Printf .

Podría decirse que este es un cambio importante, pero creo que es una mejora genuina y no una ruptura mayor que muchas otras modificaciones que hemos realizado en la salida con formato de este paquete.


Parece que estás en el camino correcto. El problema que veo con su código es que hace suposiciones sobre los valores, es decir, cuándo llama a Elem() y cuántas veces (para resolver los punteros). Para saber esto necesitas mirar el reflect.Kind . reflect.Kind . ¿Es el valor un reflect.Ptr ? Luego usa Elem() .

Una vez que tenga el valor de val.Interface() / val.String() / val.Int() puede convertir sus valores según sea necesario. Lo que uses dependerá de reflect.Kind . Para convertir un int a / desde una string , debe usar el paquete strconv .

Los paquetes encoding/json y encoding/xml realizan este tipo de trabajo. El código fuente proporciona algunos grandes ejemplos. Por ejemplo, eche un vistazo a copyValue en encoding/xml/read.go y marshalSimple en encoding/xml/marshal.go .


Un buen ejemplo de cómo analizar valores es el paquete fmt . Ver este codigo

El uso del código mencionado para que coincida con su problema se vería así:

switch val.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: m[typeField.Name] = strconv.FormatInt(val.Int(), 10) case reflect.String: m[typeField.Name] = val.String() // etc... }

Básicamente necesitas verificar todas las clases disponibles .