go标准库reflect

本文介绍了计算机科学中反射的概念,指出Golang语言实现了反射,通过官方reflect包可在运行时动态调用对象方法和属性。还阐述了反射能提高程序灵活性,介绍了使用TypeOf和ValueOf获取对象信息、用DeepEqual进行类型比较、用Swapper交换slice元素值等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述(self-representation)和监测(examination),并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

每种语言的反射模型都不同,并且有些语言根本不支持反射。Golang语言实现了反射,反射机制就是在运行时动态的调用对象的方法和属性,官方自带的reflect包就是反射相关的,只要包含这个包就可以使用。

反射可大大提高程序的灵活性,使得interface{}有更大的发挥余地

反射使用TypeOf和ValueOf函数从接口中获取目标对象信息

用反射修改对象的状态,前提是interface.data是settable,以及pointer-interface

DeepEqual

func DeepEqual(x, y interface{}) bool 

用于下列类型同类间的比较,返回为true条件:

array:

slice:length一样并且内部元素都deep equal,引用的array可以不一样

struct:类型一样,内部元素全部deep equal,包括开头小写的字段

interface:分别被赋予deepe qual的值

map:

pointer:地址一样或者指向deepe qual的值

 TypeOf和ValueOf

func TypeOf(i interface{}) Type
func ValueOf(i interface{}) Value 

举例:

type User struct {
   Id int
   Name string
   Age int
}
type Manager struct {
   User
   Title string
}
func (u User) Hello(s string)  {
   fmt.Println("hello, ", s)
}

反射基本操作

var o interface {}
a := 5
o = a
b := o.(int)  //得到int类型5
c := reflect.ValueOf(o).Int()  //得到int64类型5
func StructInfo(o interface{})  {
   t := reflect.TypeOf(o)
   fmt.Println("Type:", t.Name())
   v := reflect.ValueOf(o)
   fmt.Println("Fields:")
   for i := 0; i < t.NumField(); i++{
      f := t.Field(i)
      val := v.Field(i)
      fmt.Println(f.Name,f.Type,val)
   }
   for i := 0; i < t.NumMethod(); i++{
      m := t.Method(i)
      fmt.Println(m.Name,m.Type)
   }
}

反射匿名或嵌入字段

func AnonymousStruct(o interface{})  {
   t := reflect.TypeOf(o)
   fmt.Println(t.FieldByIndex([]int{0,0}).Name)
}

修改目标对象

func SetInt()  {
	x := 123
	v := reflect.ValueOf(&x)
	v.Elem().SetInt(56)
	fmt.Println(x)
}
func SetStruct(o interface{})  {
	v := reflect.ValueOf(o)
	if v.Kind() != reflect.Ptr || !v.Elem().CanSet(){
		fmt.Println("can not set")
		return
	}else {
		v = v.Elem()
	}
	f := v.FieldByName("Name")
	if !f.IsValid(){
		fmt.Println("have no the name")
		return
	}
	if f.Kind() == reflect.String{
		f.SetString("BYE")
	}
}

动态调用方法

func Dynamic(o interface{})  {
	v := reflect.ValueOf(o)
	vm := v.MethodByName("Hello")
	args := []reflect.Value{reflect.ValueOf("lilei")}
	vm.Call(args)
}
func main()  {
	u := User{1,"lily",18}
	m := Manager{u,"boss"}
	StructInfo(u)
	AnonymousStruct(m)
	SetStruct(&u)
	Dynamic(u)
}

Swapper

func Swapper(slice interface{}) func(i, j int)

 此方法应用于slice,返回一个方程,可以交换传入的两个索引对应的值

a := []int{0,1,2,3,4,5,6,7}
reflect.Swapper(a)(0,4)
fmt.Println(a)  //打印:[4 1 2 3 0 5 6 7]

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值