Documentation ¶
Overview ¶
Package reflectx provides extensions to the reflect package
Index ¶
- func CopyInterface[I any](value I) (ptr I, mutable bool)
- func IterateAllFields(T reflect.Type, f func(field reflect.StructField, index ...int) (stop bool)) (stopped bool)
- func IterateFields(T reflect.Type, f func(field reflect.StructField, index int) (stop bool)) (cancelled bool)
- func NameOf(T reflect.Type) string
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CopyInterface ¶
CopyInterface returns a new copy of the interface value I. I must be an interface type.
value is a copy of value, mutable indicates if the value is mutable, i.e. if it is backed by a pointer type.
If value is backed by a pointer type, the pointed-to-value is copied, and a pointer to that copy and the boolean true is returned. If the value is not backed by a non-pointer type C, and *C implements I, then a pointer to the copy of the underlying value, along with the boolean true, is returned. Otherwise, a simple copy, and the boolean false, is returned.
Example (Lift) ¶
// AsInt is an interface that returns an integer value type AsInt interface { AsInt() int } // make a *non-pointer* counter original := AsInt(counter{Value: 0}) // make a copy and increment the copy copy, _ := CopyInterface(original) copy.(interface{ Inc() }).Inc() // print the original value and the new value // the original is a plain value, the copy is a pointer! fmt.Println("original counter", original) fmt.Println("copy of counter", copy)
Output: original counter {0} copy of counter &{1}
Example (Pointer) ¶
// Inc is an interface that increments type Inc interface { Inc() } // make a pointer to a counter original := Inc(&counter{Value: 0}) // make a copy and increment the copy copy, _ := CopyInterface(original) copy.Inc() // print the value of the original counter and the copy // the copy is also a pointer fmt.Println("original counter", original) fmt.Println("copy of counter", copy)
Output: original counter &{0} copy of counter &{1}
func IterateAllFields ¶
func IterateAllFields(T reflect.Type, f func(field reflect.StructField, index ...int) (stop bool)) (stopped bool)
IterateAllFields iterates over the struct fields of T and calls f for each field. Fields are iterated in the order they are returned by reflect.Field().
When T is not a struct type, IterateAllFields panics. When T contains an embedded struct, calls IterateAllFields recursively.
The return value of f indicates if the iteration should be stopped early. If f returns true, no further calls to f are made.
IterateAllFields returns if the iteration was aborted early.
Unlike IterateFields, this function recurses into embedded structs. See also IterateFields.
Example ¶
Iterate over the fields of a struct
type Embed struct { EmbeddedField string // field in an embedded struct } type SomeStruct struct { Field string // regular field string // embedded non-struct, not called recursively Embed // an embed Another string // } // prevent unused field warning var s SomeStruct _ = s.string fmt.Println( "returned:", IterateAllFields(reflect.TypeFor[SomeStruct](), func(f reflect.StructField, index ...int) (stop bool) { fmt.Println("encountered field", f.Name, "with index", index) return false // do not stop }), )
Output: encountered field Field with index [0] encountered field string with index [1] encountered field EmbeddedField with index [2 0] encountered field Another with index [3] returned: false
Example (Cancel) ¶
stop the iteration over a subset of fields only
type Embed struct { EmbeddedField string // field in an embedded struct } type SomeStruct struct { Field string // regular field string // embedded non-struct, not called recursively Embed // an embed Another string // } // prevent unused field warning var s SomeStruct _ = s.string fmt.Println( "returned:", IterateAllFields(reflect.TypeFor[SomeStruct](), func(f reflect.StructField, index ...int) (cancel bool) { fmt.Println("encountered field", f.Name, "with index", index) return f.Name == "EmbeddedField" // cancel on embedded field }), )
Output: encountered field Field with index [0] encountered field string with index [1] encountered field EmbeddedField with index [2 0] returned: true
func IterateFields ¶
func IterateFields(T reflect.Type, f func(field reflect.StructField, index int) (stop bool)) (cancelled bool)
IterateFields iterates over the struct fields of T and calls f for each field. Fields are iterated in the order they are returned by reflect.Field().
When T is not a struct type, IterateFields panics. Unlike IterateAllFields, does not iterate over embedded fields recursively.
The return value of f indicates if the iteration should be cancelled early. If f returns true, no further calls to f are made.
IterateFields returns if the iteration was aborted early.
Unlike IterateAllFields, this function does not recurse into embedded structs. See also IterateFields.
Example ¶
Iterate over the fields of a struct
type Embed struct { EmbeddedField string // field in an embedded struct } type SomeStruct struct { Field string // regular field string // embedded non-struct, not called recursively Embed // an embed Another string // } // prevent unused field warning var s SomeStruct _ = s.string fmt.Println( "returned:", IterateFields(reflect.TypeFor[SomeStruct](), func(f reflect.StructField, index int) (stop bool) { fmt.Println("encountered field", f.Name, "with index", index) return false // do not stop }), )
Output: encountered field Field with index 0 encountered field string with index 1 encountered field Embed with index 2 encountered field Another with index 3 returned: false
Types ¶
This section is empty.