GO开发[六]:golang反射(reflect)

反射

反射:可以在运行时动态获取变量的相关信息

? Import (“reflect”)

reflect.TypeOf,获取变量的类型,返回reflect.Type类型

reflect.ValueOf,获取变量的值,返回reflect.Value类型

reflect.Value.Kind,获取变量的类别,返回一个常量

reflect.Value.Interface(),转换成interface{}类型

获取变量的值:

reflect.ValueOf(x).Float()

reflect.ValueOf(x).Int()

reflect.ValueOf(x).String()

reflect.ValueOf(x).Bool()

通过反射的来改变变量的值

reflect.Value.SetXX相关方法,比如:

reflect.Value.SetFloat(),设置浮点数

reflect.Value.SetInt(),设置整数

reflect.Value.SetString(),设置字符串

package main

import (
   "fmt"
   "reflect"
)

type Student struct {
   Name  string
   Age   int
   Score float32
}

func test(b interface{}) {
   //t是b的一个拷贝,修改t,b不会修改!
   t := reflect.TypeOf(b) //获取变量的类型,返回reflect.Type类型
   fmt.Println(t)
   v := reflect.ValueOf(b) //获取变量的值,返回reflect.Value类型
   fmt.Println(v)
   k := v.Kind() //获取变量的类别,返回一个常量
   fmt.Println(k)

   iv := v.Interface()
   stu, ok := iv.(Student)
   if ok {
      fmt.Printf("%v %T\n", stu, stu)
   }
}

func testInt(b interface{}) {
   val := reflect.ValueOf(b)
   fmt.Println(val.Elem())
   val.Elem().SetInt(100)
   //val.Elem()用来获取指针指向的变量,相当于:
   //var a *int;
   //*a = 100
   c := val.Elem().Int()
   fmt.Printf("get value  interface{} %d\n", c)
   fmt.Printf("string val:%d\n", val.Elem().Int())
}

func main() {
   var a Student = Student{
      Name:  "stu01",
      Age:   18,
      Score: 92,
   }
   test(a)

   var b int = 1
   b = 200
   testInt(&b)
   fmt.Println(b)
}

用反射操作结构体

reflect.Value.NumField()获取结构体中字段的个数

reflect.Value.Method(n).Call来调用结构体中的方法

package main

import (
    "fmt"
    "reflect"
)

type NotknownType struct {
    s1 string
    s2 string
    s3 string
}
func (n NotknownType) String() string {
    return n.s1 + "-" + n.s2 + "-" + n.s3
}

var secret interface{} = NotknownType{"greg", "learn", "go"}

func main() {
    value := reflect.ValueOf(secret) // <main.NotknownType Value>
    typ := reflect.TypeOf(secret)    // main.NotknownType
    fmt.Println(value,typ)

    knd := value.Kind() // struct
    fmt.Println(knd)

    for i := 0; i < value.NumField(); i++ {
        //value.Field(i).SetString("ningxin")
        fmt.Printf("Field %d: %v\n", i, value.Field(i))
    }

    results := value.Method(0).Call(nil)
    fmt.Printf("%T\n",results)
    fmt.Println(results)
}

反射回调函数和方法

package main

import (
   "fmt"
   "reflect"
)

type Student struct {
   Name  string
   Age   int
   Score float64
   Sex   string
}

func (s Student) Print() {
   fmt.Println("---start----")
   fmt.Println(s)
   fmt.Println("---end----")
}

func (s Student) Set(name string, age int, score float64, sex string) {
   s.Name = name
   s.Age = age
   s.Score = score
   s.Sex = sex
   fmt.Println(s)
}

func TestStruct(a interface{}) {
   val := reflect.ValueOf(a)
   kd := val.Kind()
   if kd != reflect.Ptr && val.Elem().Kind() == reflect.Struct {
      fmt.Println("expect struct")
      return
   }

   num := val.Elem().NumField()
   val.Elem().Field(0).SetString("greg")

   for i := 0; i < num; i++ {
      fmt.Printf("%d %v\n", i, val.Elem().Field(i).Kind())
   }

   fmt.Printf("struct has %d fields\n", num)
   numOfMethod := val.Elem().NumMethod()
   fmt.Printf("struct has %d methods\n", numOfMethod)

   val.Elem().Method(0).Call(nil)

   params := make([]reflect.Value,4)
   params[0]=reflect.ValueOf("hhhhhhhhh")
   params[1]=reflect.ValueOf(188888888)
   params[2]=reflect.ValueOf(59.99999)
   params[3]=reflect.ValueOf("male")
   //fmt.Println(params)
   val.Elem().Method(1).Call(params)
}

func main() {
   var a Student = Student{
      Name:  "ningxin",
      Age:   18,
      Score: 92.8,
   }
   fmt.Println(a)
   TestStruct(&a)
}

json序列化是通过反射实现的

package main

import (
   "encoding/json"
   "fmt"
   "reflect"
)

type Student struct {
   Name  string `json:"student_name"`
   Age   int
   Score float32
   Sex   string
}

func (s Student) Set(name string, age int, score float32, sex string) {
   s.Name = name
   s.Age = age
   s.Score = score
   s.Sex = sex
}

func Tagtest(a interface{}) {
   tye := reflect.TypeOf(a)
   fmt.Println("///////////",tye)
   fmt.Println(tye.Elem())
   fmt.Println(tye.Elem().Field(0))
   fmt.Println(tye.Elem().Field(0).Tag)
   tag := tye.Elem().Field(0).Tag.Get("json")
   fmt.Printf("tag=%s///////////\n", tag)
}

func main() {
   var a Student = Student{
      Name:  "stu01",
      Age:   18,
      Score: 92.8,
   }

   result, _ := json.Marshal(a)
   fmt.Println("json result:", string(result))
   Tagtest(&a)
   fmt.Println(a)
}

原文地址:https://www.cnblogs.com/gregoryli/p/8430167.html

时间: 2024-07-31 13:18:44

GO开发[六]:golang反射(reflect)的相关文章

Golang的反射reflect深入理解和示例

编程语言中反射的概念 在计算机科学领域,反射是指一类应用,它们能够自描述和自控制.也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义. 每种语言的反射模型都不同,并且有些语言根本不支持反射.Golang语言实现了反射,反射机制就是在运行时动态的调用对象的方法和属性,官方自带的reflect包就是反射相关的,只要包含这个包就可以使用. 多插一句,

golang反射初试

golang反射来自Go AST(Abstract Syntax Tree). reflect操作更多像traverse AST. t := reflect.TypeOf(obj) 使用TypeOf()获取类型信息. v := reflect.ValueOf(obj) 使用ValueOf获取值信息 如果t是Array, Slice, Map, Chan或Pointer,可以继续继续使用Elem()方法获取其元素的更多信息. Elem(): 必须是Array, Slice, Map, Chan或

go语言之行--接口(interface)、反射(reflect)详解

一.interface简介 interface(接口)是golang最重要的特性之一,Interface类型可以定义一组方法,但是这些不需要实现.并且interface不能包含任何变量. 简单的说: interface是方法的集合 interface是一种类型,并且是指针类型 interface的更重要的作用在于多态实现 interface定义 type 接口名称 interface { method1 (参数列表) 返回值列表 method2 (参数列表) 返回值列表 ... } interf

golang 反射应用(二)

golang反射应用(二) package test import ( "reflect" "testing" ) //定义适配器 func TestReflect(t *testing.T){ //声明回调函数 call1 := func(v1,v2 int){ t.Log(v1,v2) //1 2 } call2 := func(v1,v2 int,s string){ t.Log(v1,v2,s) //1 2 test2 } //定义全局变量 var ( fu

OCulus Rift 游戏开发六原则

本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/46685477 作者:cartzhang OCulus Rift 游戏开发六原则 你是一个游戏开发者?在你的生活中,你涉及游戏开发的那些点呢?你是否听说过Oculus Rift VR系统呢?你是否赞同业内的一些声音,说Oculus Rift将会是游戏的未来? 当我们游戏开发插件或一些工程时候,这有一些点,需要注意或弄清楚的.

从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用

标题:从零开始实现ASP.NET Core MVC的插件式开发(六) - 如何加载插件引用. 作者:Lamond Lu 地址:https://www.cnblogs.com/lwqlun/p/11717254.html 源代码:https://github.com/lamondlu/DynamicPlugins 前景回顾 从零开始实现ASP.NET Core MVC的插件式开发(一) - 使用Application Part动态加载控制器和视图 从零开始实现ASP.NET Core MVC的插件

golang 使用reflect反射结构体

"反射结构体"是指在程序执行时,遍历结构体中的字段以及方法. 1.反射结构体 下面使用一个简单的例子说明如何反射结构体. 定义一个结构体,包括3个字段,以及一个方法. 通过reflect包,首先查看这个结构体对应的动态类型reflect.Type和动态值reflect.Value,并查看这个结构体对应的基本类型. 接着查看结构体的字段数量,并遍历每个字段. 打印每个字段的类型.值.以及tag标签. 最后,调用结构体中的方法,并打印返回结果. 具体代码如下. package main i

类的加载到反射reflect

类的加载: 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载.连接.初始化这三个步骤来实现对这个类进行初始化. 加载: 就是指将class文件加载进入内存,并为之创建一个Class对象 任何类被使用时,系统都会创建一个Class对象 连接: 验证: 是否有正确的内部结构,并且和其他类协调一致 准备: 负责为类的静态成员分配内存,并设置默认初始化值 解析: 将类的二进制数据中的符号引用替换为直接引用 初始化:就是以前我们讲过的初始化步骤 类初始化的时机: 创建类的实例 访问类的静

JAVA学习笔记(六十一)- 反射Reflection

反射Reflection import java.lang.reflect.Modifier; /* * 反射Reflection * java.lang.Class类 */ public class Test01 { public static void main(String[] args) { String name = "tom"; // 方式一:通过对象getClass()方法 // 任意一个类的对象,都有一个getClass()方法 // 可以通过此获取获取当前对象的类型所