reflectx

package
v0.0.8 Latest Latest
Warning

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

Go to latest
Published: Aug 17, 2022 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package reflectx provides extensions to the reflect package

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func Copy added in v0.0.7

func Copy[T any](value T, copyElem bool) T

Copy returns a copy of value. When copyElem is true, and value is of kind pointer, returns a pointer to a copy of the pointed to value.

Example
// counter is a struct holding a single number

// copying a data structure directly
func() {
	original := counter{Value: 0}
	copy := Copy(original, false)
	copy.Value++
	fmt.Println("original data", original)
	fmt.Println("copy of data", copy)
}()

// copy a pointed value, which copies only the pointer
func() {
	original := &counter{Value: 0}
	copy := Copy(original, false)
	copy.Value++
	fmt.Println("original pointer", original)
	fmt.Println("copy of pointer", copy)
}()

// copy a pointed value with element which copies the data
func() {
	original := &counter{Value: 0}
	copy := Copy(original, true)
	copy.Value++
	fmt.Println("original pointer", original)
	fmt.Println("copied data", copy)
}()
Output:

original data {0}
copy of data {1}
original pointer &{1}
copy of pointer &{1}
original pointer &{0}
copied data &{1}

func IterateAllFields

func IterateAllFields(T reflect.Type, f func(field reflect.StructField, index ...int) (cancel bool)) (cancelled 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 cancelled 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 //
}

fmt.Println(
	"returned:",
	IterateAllFields(TypeOf[SomeStruct](), func(f reflect.StructField, index ...int) (cancel bool) {
		fmt.Println("encounted field", f.Name, "with index", index)
		return false // do not cancel!
	}),
)
Output:

encounted field Field with index [0]
encounted field string with index [1]
encounted field EmbeddedField with index [2 0]
encounted 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 //
}

fmt.Println(
	"returned:",
	IterateAllFields(TypeOf[SomeStruct](), func(f reflect.StructField, index ...int) (cancel bool) {
		fmt.Println("encounted field", f.Name, "with index", index)
		return f.Name == "EmbeddedField" // cancel on embedded field
	}),
)
Output:

encounted field Field with index [0]
encounted field string with index [1]
encounted field EmbeddedField with index [2 0]
returned: true

func IterateFields

func IterateFields(T reflect.Type, f func(field reflect.StructField, index int) (cancel 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 //
}

fmt.Println(
	"returned:",
	IterateFields(TypeOf[SomeStruct](), func(f reflect.StructField, index int) (cancel bool) {
		fmt.Println("encounted field", f.Name, "with index", index)
		return false // do not cancel!
	}),
)
Output:

encounted field Field with index 0
encounted field string with index 1
encounted field Embed with index 2
encounted field Another with index 3
returned: false

func MakePointerCopy added in v0.0.7

func MakePointerCopy[I any](value I) (ptr I, ok bool)

MakePointerCopy returns a new copy of value of interface type I that is backed by a pointer (if possible). ptr holds the new copy, ok indiciates if the value is indeed a pointer.

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, _ := MakePointerCopy(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 incremenets
type Inc interface {
	Inc()
}

// make a pointer to a counter
original := Inc(&counter{Value: 0})

// make a copy and increment the copy
copy, _ := MakePointerCopy(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 TypeOf

func TypeOf[T any]() reflect.Type

TypeOf returns the reflection Type that represents T.

Unlike reflect.TypeOf, this method does not require instantiating T.

Types

This section is empty.

Jump to

Keyboard shortcuts

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