Ir serie de la lengua - la reflexión

reflexión

  1. La reflexión puede adquirir diversa información dinámicamente en tiempo de ejecución de las variables, variables como el tipo (tipo), la categoría (tipo)

  2. Si la variable es una estructura, la estructura también puede obtener la información de sí mismo (incluyendo la estructura del campo, método)

  3. Por la reflexión, se puede modificar el valor de la variable que se asocia con el método de llamada

  4. El uso de la reflexión, requiere de la importación ( "reflejar")

reflexión plomo

import (
   "encoding/json"
   "fmt"
)
type Monster struct {
   Name string `json:"monsterName"`
   Age int `json:"monsterAge"`
   Sal float64 `json:"monsterSal"`
   Sex string `json:"monsterSex"`
}
func main()  {
   m := Monster{
      Name : "玉兔精",
      Age : 20,
      Sal : 888.99,
      Sex : "female",
   }
   data,_ := json.Marshal(m)
   fmt.Println("json result:", string(data))
}

Salida resultado JSON:: { "Monstername" : " fina de conejo", "monsterAge": 20, "monsterSal": 888.99, "monsterSex": "hembra"} pensar: ¿Por qué

pensamiento :

¿Por qué la serialización, la clave - valor val clave es el valor de la estructura de etiquetas, en lugar del nombre del campo, tales como: nombre, pero no: "Monstername": "fina de conejo"

reflexión plomo

El uso de la reflexión, preparado por la función de adaptador, puente

escenarios reflejados

Reflejando Hay dos escenarios comunes

  1. llamada interfaz no sabe qué función para identificar los parámetros de llamada de interfaz específicas en tiempo de ejecución en base a la entrante, refleja esta necesidad de un método o función. Este puente problemas tales como los siguientes modelos, tales propusieron previamente
func bridge(funcPtr interface{}, args ...interface{})

El primer parámetro pasado a la interfaz funcPtr punteros de función en la forma, en la forma de parámetros de la función pasa args parámetro variable, función de puente puede realizarse dinámicamente función de reflexión funcPtr

  1. Cuando la estructura de la serialización, si la estructura ha designado a la etiqueta, el reflejo también se utiliza para generar la cadena de caracteres que corresponde
type Monster struct {
   Name string `json:"monsterName"`
   Age int `json:"monsterAge"`
   Sal float64 `json:"monsterSal"`
   Sex string `json:"monsterSex"`
}

Como reflejo de las funciones y conceptos importantes

  1. reflect.TypeOf (nombre variable), tipo adquirido de la variable, el tipo de devolución reflect.Type

  2. reflect.ValueOf (nombre de la variable), obteniendo el valor de la variable, tipo de retorno reflect.Value reflect.Value es un tipo de estructura. Por reflect.Value, se puede obtener una gran cantidad de información acerca de la variable

    3) variables, la interfaz {} y reflect.Value se pueden convertir el uno al otro, esto con el desarrollo real, se utiliza con frecuencia. Dibuje esquemática

Reflejado Introducción

Escribir un caso de presentación (estructura, tipos de datos básicos, la interfaz {}, reflect.Value) para realizar operaciones básicas código reflejado demuestra

import (
   "fmt"
   "reflect"
)
//专门演示反射
func reflectTest01(b interface{}) {
   //通过反射获取的传入的变量的type,kind,值
   //1. 先获取到reflect.Type
   rTyp := reflect.TypeOf(b)
   fmt.Println("rTyp = ", rTyp)
   //2. 获取到reflect.Vakue
   rVal := reflect.ValueOf(b)
   n2 := 2 + rVal.Int()
   fmt.Println("n2 = ", n2)
   fmt.Printf("rVal = %v rVal type = %T\n", rVal, rVal)
   //下面将rVal 转成interface{}
   iV := rVal.Interface()
   //将interface{}通过断言转成需要的类型
   num2 := iV.(int)
   fmt.Println("num2 = ", num2)
}
//专门演示反射[对结构体的反射]
func reflectTest02(b interface{})  {
   //通过反射获取传入的变量的type,kind,值
   //1. 先获取到reflect.Type
   rTyp := reflect.TypeOf(b)
   fmt.Println("rTyp = ", rTyp)
   //2. 获取到reflect.Value
   rVal := reflect.ValueOf(b)

   //下面将rVal转成interface{}
   iV := rVal.Interface()
   fmt.Printf("iv = %v iv type = %T\n", iV, iV)
   //将interface{}通过断言转成需要的类型
   //这里,简单使用到检测的类型断言
   //也可以使用switch的断言形式来做的更加的灵活
   stu, ok := iV.(Student)
   if ok {
      fmt.Printf("stu.Name = %v\n", stu.Name)
   }
}

type Student struct {
   Name string
   Age int
}
type Monster struct {
   Name string
   Age int
}

func main()  {
   //演示对(结构体、基本数据类型、interface{}、reflect.Value)进行反射的基本操作
   //1. 先定义一个int
   var num int = 100
   reflectTest01(num)

   //2. 定义一个Student的实例
   stu := Student{
      Name : "tom",
      Age : 20,
   }
   reflectTest02(stu)
}
//rTyp =  int
//n2 =  102
//rVal = 100 rVal type = reflect.Value
//num2 =  100
//rTyp =  main.Student
//iv = {tom 20} iv type = main.Student
//stu.Name = tom

Notas y reflexiones detalles

1) la categoría reflect.Value.Kind obtención de variables, devuelve una constante

diferencia 2) Tipo de Kind y

Tipo es el tipo, es bueno Categoría, tipo y clase puede ser el mismo, puede ser diferente

Por ejemplo: var num int = 10 num es el int tipo, clase es int

Por ejemplo: var Stu Stu Tipo de estudiante es pKg1.Student, Kind es una estructura

  1. Al permitir que los interruptores variables reflexión entre la interfaz {} y Reflect.Value, esta pintado esquemática y explicar el inicio rápido en el frontal de la caja, donde el aspecto de código de cómo materializa
  2. Uso de reflexión para obtener el valor de la variable (y el correspondiente tipo de devolución) requerido para que coincida con el tipo de datos, como x es de tipo int, entonces debería usar reflect.Value (x) .INT (), pero no el otro, o informado pánico
  3. Variable es modificado por la reflexión, nota que cuando se usa el método para establecer la setXXX deseada se logra mediante un tipo de puntero correspondiente, a fin de cambiar el valor de la variable pasada, mientras que se requiere para reflect.Value.Elem () método
import (
   "fmt"
   "reflect"
)

func testInt(b interface{})  {
   val := reflect.ValueOf(b)
   fmt.Printf("val type = %T\n", val)
   val.Elem().SetInt(110)
   fmt.Printf("val = %v\n", val)
}
func main()  {
   var num int = 20
   testInt(&num)
   fmt.Println("num = ", num)
}
//val type = reflect.Value
//val = 0xc000054080
//num =  110
  1. reflect.Valut.Elem () debe entender cómo

La práctica reflexiva

  1. Para una variable var v float64 = 1,2, utilizando la reflexión sobre su reflect.Value, entonces adquiere el tipo correspondiente, la clase y valor, y convertidos en la interfaz de reflect.Value {}, entonces la interfaz {} se convierte en float64

  2. Ver las secciones del código para determinar si apropiado, ¿por qué

import (
   "fmt"
   "reflect"
)

func main()  {
   var str string = "tom" // ok
   fs := reflect.ValueOf(&str) // ok fs -> string
   //fs.SetString("jack")  //error
   fs.Elem().SetString("jack")
   fmt.Printf("%v\n", str)
}
//jack

Como reflejo de las mejores prácticas

  1. El uso de la reflexión para atravesar la estructura exterior, la estructura de la llamada al método, y adquiere el valor de la estructura de etiquetas
import (
   "fmt"
   "reflect"
)
//定义一个Monster结构体
type Monster struct {
   Name  string `json:"name"`
   Age int `json:"monster_age"`
   Score float32 `json:"成绩"`
   Sex string
}
//方法,返回两个数的和
func (s Monster) GetSum(n1, n2 int) int {
   return n1 + n2
}
//方法,接收四个值,给s赋值
func (s Monster) Set(name string, age int, score float32, sex string) {
   s.Name = name
   s.Age = age
   s.Score = score
   s.Sex = sex
}
//方法,显示s的值
func (s Monster) Print() {
   fmt.Println("---start---")
   fmt.Println(s)
   fmt.Println("---end---")
}
func TestStruct(a interface{})  {
   //获取reflect.Type类型
   typ := reflect.TypeOf(a)
   //获取reflect.Value类型
   val := reflect.ValueOf(a)
   //获取到a对应的类别
   kd := val.Kind()
   //如果传入的不是struct,就退出
   if kd != reflect.Struct {
      fmt.Println("expect struct")
      return
   }
   //获取到该结构体有几个字段
   num := val.NumField()
   fmt.Printf("struct has %d fields \n", num) //4
   //变量结构体的所有字段
   for i := 0; i < num; i++ {
      fmt.Printf("Field %d: 值为=%v\n", i, val.Field(i))
      //获取到struct标签,注意需要通过reflect.Type来获取tag标签的值
      tagVal := typ.Field(i).Tag.Get("json")
      //如果该字段于tag标签就显示,否则就不显示
      if tagVal != "" {
         fmt.Printf("Field %d: tag 为 = %v\n", i, tagVal)
      }
   }
   //获取到该结构体有多少个方法
   numOfMethod := val.NumMethod()
   fmt.Printf("struct has %d methods \n", numOfMethod)
   //var params []reflect.Value
   //方法的排序默认是按照函数名的排序(ASCII码)
   val.Method(1).Call(nil)//获取到第二个方法,调用它

   //调用结构体的第1个方法Method(0)
   var params []reflect.Value //声明了[]reflect.Value
   params = append(params, reflect.ValueOf(10))
   params = append(params, reflect.ValueOf(40))
   res := val.Method(0).Call(params) // 传入的参数是[]reflect.Value ,返回[]reflect.Value
   fmt.Println("res = ", res[0].Int()) //返回结果,返回的结果是[]reflect.Value
}
func main()  {
   //创建了一个Monster实例
   var a Monster = Monster{
      Name: "黄鼠狼精",
      Age: 400,
      Score: 30.8,
   }
   //将Monster实例传递给TestStruct函数
   TestStruct(a)
}
//struct has 4 fields 
//Field 0: 值为=黄鼠狼精
//Field 0: tag 为 = name
//Field 1: 值为=400
//Field 1: tag 为 = monster_age
//Field 2: 值为=30.8
//Field 2: tag 为 = 成绩
//Field 3: 值为=
//struct has 3 methods 
//---start---
//{黄鼠狼精 400 30.8 }
//---end---
//res =  50
  1. Se utiliza para llegar a la estructura de la reflexión etiqueta, el valor del campo de desplazamiento, modificar el valor del campo, el método llama a la estructura (requisito: a través de la dirección de entrega se ha completado, puede ser modificada por la caja frontal)

  2. Define dos funciones test1 y test2, definen una función de adaptador unitario como una interfaz

  3. operación Reflexión usando cualquier tipo de estructura

  4. El uso de la reflexión para crear y manipular la estructura

  5. preparación Cal de una estructura, y hay dos campos Num1 Num2

  6. Método GetSub (nombre de la cadena)

  7. Todos los campos de información que refleja la estructura de recorrido Cal

  8. Utiliza la reflexión completar la llamada, se emite en forma de GetSub "Tom completó resta, 8--3 = 5"

Supongo que te gusta

Origin www.cnblogs.com/zisefeizhu/p/12643858.html
Recomendado
Clasificación