11.反射

反射初识

反射是指在程序运行期间对程序本身进行访问和修改的能力

TypeOf

使用reflect.TypeOf()函数可以获得任意值的类型对象

package main

import (
	"fmt"
	"reflect"
)

// reflect demo

func reflectType(x interface{}) {
	// 此时不知道别人调用这个函数的时候会传进来什么类型的变量
	// 方式1. 通过类型断言
	// 方式2. 借助反射
	obj := reflect.TypeOf(x)
	// fmt.Printf("obj: %v\n", obj)
  fmt.Println(obj, obj.Name(), obj.Kind()) // .name()类型,.kind()种类
	fmt.Printf("%T\n", obj) // *reflect.rtype reflect内置类型的一个指针
}

func main() {
	var a float32 = 1.23
	reflectType(a)
}

在反射中,数组、切片、map、指针等类型的变量,.Name返回都是空

ValueOf

reflect.ValueOf()拿到原始值

func reflectValue (x interface{}){
  v:=reflect.ValueOf(x)
  fmt.Printf("%v, %T\n", v, v)
}

func main(){
  aa:= 100
}

结构体反射

方法 说明
Field(i int) StructField 根据索引,返回索引对应的结构体字段的信息。
NumField() int 返回结构体成员字段数量。
FieldByName(name string) (StructField, bool) 根据给定字符串返回字符串对应的结构体字段的信息。
FieldByIndex(index []int) StructField 多层成员访问时,根据 []int 提供的每个结构体的字段索引,返回字段的信息。
FieldByNameFunc(match func(string) bool) (StructField,bool) 根据传入的匹配函数匹配需要的字段。
NumMethod() int 返回该类型的方法集中方法的数目
Method(int) Method 返回该类型方法集中的第i个方法
MethodByName(string)(Method, bool) 根据方法名返回该类型方法集中的方法
package main

import (
	"fmt"
	"reflect"
)

// 结构体反射

type student struct {
	Name  string `json:"name" ini:"s_name"`
	Score int    `json:"score" ini:"s_score"`
}

func main() {
	stu1 := student{
		Name:  "小王子",
		Score: 49,
	}

	// 通过反射获取结构体中的所有字段信息
	t := reflect.TypeOf(stu1)
	fmt.Printf("t.Name(): %v  ", t.Name())
	fmt.Printf("t.Kind(): %v\n", t.Kind())

	// 遍历结构体变量的所有字段
	for i := 0; i < t.NumField(); i++ {
		// 根据结构体字段的索引去获取字段
		filedObj := t.Field(i)
		fmt.Printf("filedObj.Name: %v\n", filedObj.Name)
		fmt.Printf("filedObj.Type: %v\n", filedObj.Type)
		fmt.Printf("filedObj.Tag: %v\n", filedObj.Tag)

		fmt.Println(filedObj.Tag.Get("json"), filedObj.Tag.Get("ini"))

	}

	// 根据名字去取结构体中的字段
	filed, ok := t.FieldByName("Score")
	if ok {
		fmt.Printf("name:%v type:%v tag:%v", filed.Name, filed.Type, filed.Tag)
	}
}

反射能让我们写出更加灵活的代码,但不应被滥用:

  1. 基于反射的代码极其脆弱,反射中的错误会在真正运行的时候才会引发panic,那很可能是在代码写完的很长时间以后
  2. 大量的反射代码通常难以理解
  3. 反射的性能低下,基于反射的代码通常比正常代码运行速度慢一到两个量级
posted @ 2025-06-25 10:48  L大官  阅读(11)  评论(0)    收藏  举报