teniendo un momento difícil trabajar con la estructura de los campos de uso de reflect paquete. en particular, no han descubierto la manera de establecer el valor del campo.

t de tipo struct { fi int; fs string } 
var r t = t{ 123, "jblow" } 
var i64 int64 = 456 
  1. recibiendo el Nombre de campo de la i – esto parece funcionar

    var field = reflect.TypeOf(r).Field(i).Name

  2. a obtener valor de campo i) de la interfaz{}, b) int – esto parece funcionar

    var iface interface{} = reflect.ValueOf(r).Field(i).Interface()

    var i int = int(reflect.ValueOf(r).Field(i).Int())

  3. el valor de ajuste de campo i – trate de un pánico

    reflect.ValueOf(r).Field(i).SetInt( i64 )

    el pánico: reflejar.Valor·SetInt utilizando el valor obtenido utilizando dejados de exportar campo

    suponiendo que no se como nombres de campo «id» y «name», por lo que cambió el nombre a «Id» y «Name»

    a) es esta suposición correcta?

    b) si es correcto, pensó que no era necesario ya que en el mismo archivo /paquete

  4. el valor de ajuste de campo i – dos (con los nombres de campo en mayúsculas ) – pánico

    reflect.ValueOf(r).Field(i).SetInt( 465 )

    reflect.ValueOf(r).Field(i).SetInt( i64 )

    el pánico: reflejar.Valor·SetInt utilizando unaddressable valor


Instrucciones de abajo por @peterSO son completos y de alta calidad

Cuatro. esto funciona:

reflect.ValueOf(&r).Elem().Field(i).SetInt( i64 )

él los documentos que los nombres de campo deben ser exportable (comenzar con letra mayúscula)

  • el ejemplo más cercano que pude encontrar para alguien con reflect para el conjunto de datos fue comments.gmane.org/gmane.comp.lang.go.general/35045, pero incluso allí se utiliza json.Unmarshal de hacer un verdadero trabajo sucio
  • (el comentario de arriba es obsoleto)
InformationsquelleAutor cc young | 2011-06-18

2 Comentarios

  1. 127

    Go está disponible como código de fuente abierta. Una buena manera de aprender acerca de la reflexión es ver cómo el núcleo de Ir a los desarrolladores utilizar. Por ejemplo, el Ir fmt y json paquetes. El paquete de documentación tiene enlaces a los archivos de código fuente bajo el título de los archivos del Paquete.

    El Ir json paquete de alguaciles y resuelve JSON desde y para Ir estructuras.


    Aquí un paso a paso ejemplo la que establece el valor de un struct campo, mientras que con cuidado evitando los errores.

    El Ir reflejar paquete tiene un CanAddr función.

    func (v Value) CanAddr() bool

    CanAddr devuelve true si el valor de la
    la dirección puede ser obtenida con Addr.
    Dichos valores son llamados direccionable. Un
    valor es direccionable si es un
    elemento de un sector, un elemento de un
    direccionable de la matriz, un campo de un
    direccionable de la estructura, o el resultado de
    desreferenciar un puntero. Si CanAddr
    devuelve false, llamando Addr se
    el pánico.

    El Ir reflejar paquete tiene un CanSet función, que, si true, implica que CanAddr es también true.

    func (v Value) CanSet() bool

    CanSet devuelve true si el valor de v
    puede ser cambiado. Un Valor puede ser cambiado
    sólo si es direccionable y no fue
    obtenidos por el uso de la dejados de exportar
    estructura de los campos. Si CanSet devuelve
    falso, llamar a Set o cualquier
    tipo específico de setter (por ejemplo, SetBool,
    SetInt64) va a entrar en pánico.

    Tenemos que asegurarnos de que podemos Set la struct campo. Por ejemplo,

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    func main() {
        type t struct {
            N int
        }
        var n = t{42}
        //N at start
        fmt.Println(n.N)
        //pointer to struct - addressable
        ps := reflect.ValueOf(&n)
        //struct
        s := ps.Elem()
        if s.Kind() == reflect.Struct {
            //exported field
            f := s.FieldByName("N")
            if f.IsValid() {
                //A Value can be changed only if it is 
                //addressable and was not obtained by 
                //the use of unexported struct fields.
                if f.CanSet() {
                    //change value of N
                    if f.Kind() == reflect.Int {
                        x := int64(7)
                        if !f.OverflowInt(x) {
                            f.SetInt(x)
                        }
                    }
                }
            }
        }
        //N at end
        fmt.Println(n.N)
    }
    
    Output:
    42
    7

    Si podemos estar seguros de que todas las comprobaciones de errores son innecesarios, en el ejemplo se simplifica,

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    func main() {
        type t struct {
            N int
        }
        var n = t{42}
        fmt.Println(n.N)
        reflect.ValueOf(&n).Elem().FieldByName("N").SetInt(7)
        fmt.Println(n.N)
    }
    • Dan! en algún lugar hay una respuesta, pero cuatro horas de trabajo en el json pkg no han dado a mí. volver a la reflejan pkg, tirando info es bastante sencillo, pero los datos de configuración requiere algo de magia negra para que me encantaría ver un ejemplo sencillo en alguna parte!
    • Excelente! si alguna vez estás en Tailandia por favor, déjame tratar de usted a una cerveza o dos o tres! muchas gracias
    • Gran ejemplo práctico, en este artículo totalmente desmitificado para mí golang.org/doc/articles/laws_of_reflection.html
    • Ejemplo impresionante.Aquí es el patio de recreo de la muestra el mismo código, play.golang.org/p/RK8jR_9rPh
    • Esto no establecer una estructura de campo. Esto establece un campo en un puntero a struct. Obviamente, esto no es responder a la pregunta OP preguntó.
    • omg, ¿por qué ir tan doloroso para su uso. Se quejan, se quejan se quejan. Repita los pasos anteriores para todos los tipos de datos diferentes y puede ver a lo que me refiero
    • Reflexionar es una cosa terrible. Programador puede visitar el unexport campos como la fmt.Printf nos pueden mostrar el unexport campo. Gracias golang equipo, que no permiten a los programadores cambiar el unexport campo. O algo ridículo vendrá.

  2. 11

    Esto parece funcionar:

    package main
    
    import (
        "fmt"
        "reflect"
    )
    
    type Foo struct {
        Number int
        Text string
    }
    
    func main() {
        foo := Foo{123, "Hello"}
    
        fmt.Println(int(reflect.ValueOf(foo).Field(0).Int()))
    
        reflect.ValueOf(&foo).Elem().Field(0).SetInt(321)
    
        fmt.Println(int(reflect.ValueOf(foo).Field(0).Int()))
    }

    Imprime:

    123
    321
    • gracias! ahora que he leído peterSO notas, esto tiene el sentido perfecto. Yo estaba usando foo, no &foo, por lo que no podía ser cambiado, y estaba seguro de qué Elem() se acerca.

Dejar respuesta

Please enter your comment!
Please enter your name here