介绍
在实际业务开发中, 经常需要用到反射的能力, 比如结合远程配置动态修改结构体的字段, 这样无需发布即可实现功能变更, 再比如拓展插件的场景, 使用表驱动的方式调用一些异构的函数(无法抽象为接口)等. 这里对常用的操作进行了 getter, setter 的封装, 并增强了一些能力, 比如支持设置多层嵌套结构体的字段, 针对结构体指针自动创建等.
地址: https://github.com/morrisxyang/xreflect
中文文档: https://github.com/morrisxyang/xreflect/blob/main/README_CN.md 如果觉得有用欢迎 Star 和 PR, 有问题直接提 Issue
xreflect
一个简单的, 易用的反射工具库.
主要支持如下特性:
-
设置结构体字段值, 支持通过路径比如
A.B.C设置嵌套结构体字段的值 -
获取结构体字段的值, 类型, Tag 等.
-
遍历结构体所有字段, 支持
select模式和range模式, 如果使用深度遍历方法比如FieldsDeep将遍历所有嵌套结构. -
函数调用, 方法调用, 支持可变参数.
-
新建实例, 判断接口实现等等.
安装和文档
安装命令 go get github.com/morrisxyang/xreflect.
文档见 https://pkg.go.dev/github.com/morrisxyang/xreflect
快速开始
设置嵌套结构体字段值
person := &Person{ Name: "John", Age: 20, Country: Country{ ID: 0, Name: "Perk", }, } _ = SetEmbedField(person, "Country.ID", 1) // Perk's ID: 1 fmt.Printf("Perk's ID: %d \n", person.Country.ID) 调用函数
var addFunc = func(nums ...int) int { var sum int for _, num := range nums { sum += num } return sum } res, _ := CallFunc(addFunc1, 1, 2, 3) // 6 fmt.Println(res[0].Interface()) 核心方法
FieldX
- func Field(obj interface{}, fieldName string) (reflect.Value, error)
- func FieldValue(obj interface{}, fieldName string) (interface{}, error)
- func EmbedField(obj interface{}, fieldPath string) (reflect.Value, error)/li>
- func EmbedFieldValue(obj interface{}, fieldPath string) (interface{}, error)
- func Fields(obj interface{}) (map[string]reflect.Value, error)
- func FieldsDeep(obj interface{}) (map[string]reflect.Value, error)
- func RangeFields(obj interface{}, f func(string, reflect.StructField, reflect.Value) bool) error
- func SelectFields(obj interface{}, f func(string, reflect.StructField, reflect.Value) bool) (map[string]reflect.Value, error)
- etc.
SetX
-
func SetEmbedField(obj interface{}, fieldPath string, fieldValue interface{}) error
-
func SetField(obj interface{}, fieldName string, fieldValue interface{}) error
-
func SetPrivateField(obj interface{}, fieldName string, fieldValue interface{}) error
-
etc.
StrcutFieldX
-
func StructField(obj interface{}, fieldName string) (reflect.StructField, error)
-
func StructFieldTagValue(obj interface{}, fieldName, tagKey string) (string, error)
-
func EmbedStructField(obj interface{}, fieldPath string) (reflect.StructField, error)
-
func StructFields(obj interface{}) ([]reflect.StructField, error)
-
func StructFieldsFlatten(obj interface{}) ([]reflect.StructField, error)
-
func RangeStructFields(obj interface{}, f func(int, reflect.StructField) bool) error
-
etc.
FuncX
-
func CallFunc(fn interface{}, args ...interface{}) ([]reflect.Value, error)
-
func CallMethod(obj interface{}, method string, params ...interface{}) ([]reflect.Value, error)
-
etc.
Others
- func NewInstance(obj interface{}) interface{}
- func Type(obj interface{}) reflect.Type
- func TypePenetrateElem(obj interface{}) reflect.Type
- func Value(obj interface{}) reflect.Value
- func ValuePenetrateElem(obj interface{}) reflect.Value
- etc.
FAQ
Field 和 StrcutField 的区别是?
Field 返回 reflect.Value, StrcutField 返回 reflect.StrcutField.
