go语言---反射-reflect

go语言—反射reflect
  1. 在go语言标准库中reflect包提供了运行时反射机制,所谓的运行时反射,就是程序运行过程中动态操作结构体;
  2. 当变量存储结构体属性名称,想要对结构体这个属性赋值或查看时,就可以使用反射;
  3. 反射还可以用作判断变量类型;
  4. reflect中最重要的两个类型:reflect.Typereflect.Value;
  5. 获取到TypeValue的函数: reflect.TypeOf(interface{})返回Type,reflect.ValueOf(interface{})返回Value;
  6. 反射时获取的如果是指针类型,需要使用Elem()来获取指针指向地址的封装,地址的值必须通过调用Elem()才可以继续操作;
  7. 如果需要修改属性的内容,要求结构体中属性名称首字母大写才可以设置;
  8. 结构体支持标记(tag),标记通常都是通过反射技术获取到,结构体标记语法:
    type 结构体名称 struct {
    	属性名 类型 `key:"Value"`
    }
    
package main

import (
	"fmt"
	"reflect"
)

func main() {
	//judgeType()
	//getStructValue()
	//setAttr()
	getTags()
}


// 判断变量类型:TypeOf()
func judgeType() {
	a := 2.4
	b := 12
	c := "hello world"
	fmt.Println(reflect.TypeOf(a))  // float64
	fmt.Println(reflect.ValueOf(a)) // 2.4
	fmt.Println(reflect.TypeOf(b))  // int
	fmt.Println(reflect.ValueOf(b)) // 12
	fmt.Println(reflect.TypeOf(c))  // string
	fmt.Println(reflect.ValueOf(c)) // hello world

}

// 获取结构体属性的值
type People4 struct {
	Id   int  `xml:"id"`  // 这里常用xml,但不一定非要用xml; 后面有获取标签的操作
	Name string  `xml:"name"`
}

func getStructValue() {
	p1 := People4{1001, "张三"}

	// 获取p1的值
	v := reflect.ValueOf(p1)

	// 获取属性个数,如果v不是结构体类型则panic
	fmt.Println("属性个数: ", v.NumField()) // 属性个数: 2

	// 利用索引来获取
	fmt.Println(v.FieldByIndex([]int{0}))  // 1001
	fmt.Println(v.FieldByIndex([]int{1}))  // 张三

	// 获取第0个属性,id,并转化为int64类型
	fmt.Println(v.Field(0).Int()) // 1001

	// 获取第1个属性,并转化为string类型
	fmt.Println(v.Field(1).String()) // 张三

	// 根据名字获取类型,并把类型名称转化为string类型
	idValue := v.FieldByName("Id")
	fmt.Println(idValue.Kind().String()) // int

}


// 通过反射来获取结构体的属性
func setAttr()  {

	// 这里需要使用new()来创建指针类型,否则传递值类型无法实现;或者使用&取地址比如reflect.ValueOf(&p2)
	p2 := new(People4)
	v := reflect.ValueOf(p2).Elem()  // 由于这里传递的p2是指针类型,所以需要再调用其Elem()获取到指针中对应的内容
	content := "Id"
	name := "Name"
	fmt.Println(v.FieldByName(content).CanSet())  // true   // 如果上面People结构体中的属性首字母小写就不可以被修改;

	// 设置属性值
	v.FieldByName(content).SetInt(1003)
	v.FieldByName(name).SetString("李四")
	fmt.Println(p2)  // &{1003 李四}

}

// 获取标签内容
func getTags() {
	t:= reflect.TypeOf(People4{})
	fmt.Println(t.FieldByName("Name"))  // {Name  string xml:"name" 8 [1] false} true
	name, _ := t.FieldByName("Name")
	fmt.Println(name)  // {Name  string xml:"name" 8 [1] false}
	fmt.Println(name.Tag)  // xml:"name"
	fmt.Println(name.Tag.Get("xml"))  // name
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值