Documentation
¶
Overview ¶
Package reflectx provides extensions to the reflect package
Index ¶
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) ¶
package main
import (
"fmt"
"go.tkw01536.de/pkglib/reflectx"
)
// counter is used for testing.
//
//nolint:recvcheck // testing code
type counter struct {
Value int
}
func (c *counter) Inc() {
c.Value++
}
func (c counter) AsInt() int {
return c.Value
}
func main() {
// 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 cp and increment the cp
cp, _ := reflectx.CopyInterface(original)
cp.(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", cp)
}
Output: original counter {0} copy of counter &{1}
Example (Pointer) ¶
package main
import (
"fmt"
"go.tkw01536.de/pkglib/reflectx"
)
// counter is used for testing.
//
//nolint:recvcheck // testing code
type counter struct {
Value int
}
func (c *counter) Inc() {
c.Value++
}
func (c counter) AsInt() int {
return c.Value
}
func main() {
// Inc is an interface that increments
type Inc interface {
Inc()
}
// make a pointer to a counter
original := Inc(&counter{Value: 0})
// make a cp and increment the cp
cp, _ := reflectx.CopyInterface(original)
cp.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", cp)
}
Output: original counter &{0} copy of counter &{1}
func IterAllFields ¶
IterateAllFields iterates over the struct fields of typ and their indexes. Fields are iterated in the order they are returned by reflect.Field().
When typ is not a struct type, IterAllFields panics. When typ contains an embedded struct, calls IterAllFields recursively.
Unlike IterFields, this function recurses into embedded structs. See also IterFields.
Example ¶
Iterate over the fields of a struct.
package main
import (
"fmt"
"reflect"
"go.tkw01536.de/pkglib/reflectx"
)
func main() {
type Embed struct {
EmbeddedField string // field in an embedded struct
}
type SomeStruct struct {
Field string // regular field
//lint:ignore U1000 // false positive: used by TypeFor call below
string // embedded non-struct, not called recursively
Embed // an embed
Another string // another field
}
for f, index := range reflectx.IterAllFields(reflect.TypeFor[SomeStruct]()) {
fmt.Println("encountered field", f.Name, "with index", index)
}
}
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]
func IterFields ¶
IterFields returns an iterator that iterates over the struct fields of typ in the order they are returned by reflect.Field.
When typ is not a struct type, IterFields panics. Unlike IterAllFields, does not iterate over embedded fields recursively.
Example ¶
Iterate over the fields of a struct.
package main
import (
"fmt"
"reflect"
"go.tkw01536.de/pkglib/reflectx"
)
func main() {
type Embed struct {
EmbeddedField string // field in an embedded struct
}
type SomeStruct struct {
Field string // regular field
//lint:ignore U1000 // false positive: used by TypeFor below
string // embedded non-struct, not called recursively
Embed // an embed
Another string //
}
for f, index := range reflectx.IterFields(reflect.TypeFor[SomeStruct]()) {
fmt.Println("encountered field", f.Name, "with index", index)
}
}
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
Example (Early) ¶
Iterate over the fields of a struct, stopping early.
package main
import (
"fmt"
"reflect"
"go.tkw01536.de/pkglib/reflectx"
)
func main() {
type Embed struct {
EmbeddedField string // field in an embedded struct
}
type SomeStruct struct {
Field string // regular field
//lint:ignore U1000 // false positive: used by TypeFor below
string // embedded non-struct, not called recursively
Embed // an embed
Another string //
}
for f, index := range reflectx.IterFields(reflect.TypeFor[SomeStruct]()) {
fmt.Println("encountered field", f.Name, "with index", index)
break
}
}
Output: encountered field Field with index 0
Types ¶
This section is empty.