go反射获取类型对象与值、go反射获取指针名称和类型、golang反射对象的空值处理、golang反射值对象修改变量的值

一、反射获取类型对象与值

package main

import (
	"fmt"
	"reflect"
)

func main() {
     
	a := 36
	atype := reflect.TypeOf(a)
	fmt.Println(atype.Name()) //获取类型名称为int
	avalue := reflect.ValueOf(a)
	fmt.Println(avalue.Int()) //获取具体的数值
}

二、反射获取结构体类型名称与类型

package main

import (
	"fmt"
	"reflect"
)

type myobject struct {
     
	Name string
	Sex  int
	Age  int `json:"age"`
}

func main() {
     
	typeof := reflect.TypeOf(myobject{
     })
	fmt.Println(typeof.Name()) //获取反射类型对象  myobject 
	fmt.Println(typeof.Kind()) //获取反射类型种类  myobject 
}

三、反射获取指针名称和类型

package main

import (
	"fmt"
	"reflect"
)

type myobject struct {
     
	Name string
	Sex  int
	Age  int `json:"age"`
}

func main() {
     
	typeof := reflect.TypeOf(&myobject{
     })
	fmt.Println(typeof.Elem().Name()) //获取指针类型指向的元素类型的名称
	fmt.Println(typeof.Elem().Kind()) //获取指针类型指向的元素类型的种类
}

四、反射获取结构体成员的类型

package main

import (
	"fmt"
	"reflect"
)

type myobject struct {
     
	Name string
	Sex  int
	Age  int `json:"age"`
}


func main() {
     
	typeof := reflect.TypeOf(myobject{
     })
	fieldnum := typeof.NumField() //获取结构体成员字段的数量
	for i := 0; i < fieldnum; i++ {
     
		fieldname := typeof.Field(i) //索引对应的字段信息
		fmt.Println(fieldname)
		name, err := typeofmystruct.FieldByName("Name")//根据指定的字符串返回对应的字段信息
		fmt.Println(name, err)
	}

}

五、反射值对象获取任意值

package main

import (
	"fmt"
	"reflect"
)

func main() {
     
	a := 2020
	valof := reflect.ValueOf(a) //先通过reflect.ValueOf 获取反射的值对象
	fmt.Println(valof)
	//再通过值对象通过类型断言转换为指定类型
	fmt.Println(valof.Interface()) //转换为interface{} 类型
	fmt.Println(valof.Int())       //将值以int类型返回
}

注意:.Interface() 将值以interface{}任意类型返回。还有各自对应的类型, .Int()、.Uint() 、.Floact() 、.Bool() 、.Bytes() 、.String()。

六、反射获取结构体的成员字段的值

package main

import (
	"fmt"
	"reflect"
)

type myobject struct {
     
	Name string
	Age  int
}

func main() {
     
	h := myobject{
     "测试", 20}
	fmt.Println(h)
	hofvalue := reflect.ValueOf(h)             //获取结构体的reflect.Value对象。
	for i := 0; i < hofvalue.NumField(); i++ {
      //循环结构体内字段的数量
		//获取结构体内索引为i的字段值
		fmt.Println(hofvalue.Field(i).Interface())
	}
	fmt.Println(hofvalue.Field(1).Type()) //获取结构体内索引为1的字段的类型

}

七、反射对象的空值处理

package main

import (
	"fmt"
	"reflect"
)

func main() {
     
	var a *int                              //声明一个变量a为nil的空指针
	fmt.Println(reflect.ValueOf(a).IsNil()) //判断是否为nil 返回true
	//当reflect.Value不包含任何信息,值为nil的时候IsValid()就返回false
	fmt.Println(reflect.ValueOf(nil).IsValid())
}

八、反射值对象修改变量的值

package main

import (
	"fmt"
	"reflect"
)

func main() {
     
	//声明变量a
	a := 100
	fmt.Printf("a的内存地址为:%p\n", &a)
	//获取变量a的反射类型reflect.Value 的地址
	rf := reflect.ValueOf(&a)
	fmt.Println("通过反射获取变量a的地址:", rf)
	//获取a的地址的值
	rval := rf.Elem()
	fmt.Println("反射a的值:", rval)
	//修改a的值
	rval.SetInt(200)
	fmt.Println("修改之后反射类型的值为:", rval.Int())
	//原始值也被修改
	fmt.Println("原始a的值也被修改为:", a)
}

注意

SetInt(x) 设置值为x, 类型必须是int类型。
SetUint(x) 设置值为x, 类型必须是uint类型。
SetFloat(x) 设置值为x, 类型必须是float32或者float64类型。
SetBool(x) 设置值为x, 类型必须是bool类型。
SetBytes(x) 设置值为x, 类型必须是[]Byte类型。
SetString(x) 设置值为x, 类型必须是string类型。

九、反射调用函数方法

package main

import (
	"fmt"
	"reflect"
)

func myfunc(a, b int) int {
     
	return a + b
}

func main() {
     
	r_func := reflect.ValueOf(myfunc)
	//设置函数需要传入的参数也必须是反射类型
	params := []reflect.Value{
     reflect.ValueOf(10), reflect.ValueOf(20)}
	//反射调用函数
	res := r_func.Call(params)
	//获取返回值
	fmt.Println(res[0].Int())
}

你可能感兴趣的