reflectx

package
v0.0.0-...-c5cf874 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 20, 2024 License: MIT Imports: 2 Imported by: 3

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

func CopyInterface[I any](value I) (ptr I, mutable bool)

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

func NameOf

func NameOf(T reflect.Type) string

NameOf returns the fully qualified name for T.

A fully qualified name consists of the package path, followed by a ".", followed by the type name. Builtin types have the empty package path. Types that are not named, return the empty string

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL