A simple and user-friendly reflection utility library.
The xreflect package aims to provide developers with high-level abstractions over the Go standard reflect library. This library's API is often considered low-level and unintuitive, making simple tasks like setting structure field values more complex than necessary.
The main features supported are:
-
Setting the values of structure fields, supporting nested structure field values by using paths such as
A.B.C
. -
Getting the values, types, tags, etc., of structure fields.
-
Traversing all fields of a structure, supporting both
select
mode andrange
mode. If a deep traversal method likeFieldsDeep
is used, it will traverse all nested structures. -
Function calls and method calls, supporting variadic parameters.
-
Creating new instances, checking interface implementations, and more.
Install using go get github.com/morrisxyang/xreflect
.
Full documentation is available at https://pkg.go.dev/github.com/morrisxyang/xreflect
Set nested struct field value
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)
Find json tag
type Person struct {
Name string `json:"name" xml:"_name"`
}
p := &Person{}
// json:"name" xml:"_name"
fmt.Println(StructFieldTag(p, "Name"))
// name <nil>
fmt.Println(StructFieldTagValue(p, "Name", "json"))
// _name <nil>
fmt.Println(StructFieldTagValue(p, "Name", "xml"))
Filter instance fields (deep traversal)
type Person struct {
id string
Age int `json:"int"`
Name string `json:"name"`
Home struct {
Address string `json:"address"`
}
}
p := &Person{}
fields, _ := SelectFieldsDeep(p, func(s string, field reflect.StructField, value reflect.Value) bool {
return field.Tag.Get("json") != ""
})
// key: Age type: int
// key: Name type: string
// key: Home.Address type: string
for k, v := range fields {
fmt.Printf("key: %s type: %v\n", k, v.Type())
}
Call a function
var addFunc = func(nums ...int) int {
var sum int
for _, num := range nums {
sum += num
}
return sum
}
res, _ := CallFunc(addFunc, 1, 2, 3)
// 6
fmt.Println(res[0].Interface())
- 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)
- 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.
-
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.
-
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.
-
func CallFunc(fn interface{}, args ...interface{}) ([]reflect.Value, error)
-
func CallMethod(obj interface{}, method string, params ...interface{}) ([]reflect.Value, error)
-
etc.
- 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.
Field
returns reflect.Value
, while StructField
returns reflect.StructField
.