Documentation
¶
Index ¶
- Constants
- func DeepFields(typ interface{}) []r.StructField
- func Deref(val interface{}) r.Value
- func DerefFunc(val interface{}) r.Value
- func DerefKind(val interface{}) r.Kind
- func DerefMap(val interface{}) r.Value
- func DerefPtr(val interface{}) r.Value
- func DerefSlice(val interface{}) r.Value
- func DerefStruct(val interface{}) r.Value
- func DerefType(val interface{}) r.Type
- func DerefWithKind(src interface{}, kind r.Kind) r.Value
- func ElemType(val interface{}) r.Type
- func Fields(typ interface{}) []r.StructField
- func FuncName(val interface{}) string
- func Interface(val r.Value) interface{}
- func IsColl(val interface{}) bool
- func IsEmbed(val r.StructField) bool
- func IsEmptyColl(val interface{}) bool
- func IsKindColl(kind r.Kind) bool
- func IsKindNilable(kind r.Kind) bool
- func IsNil(val interface{}) bool
- func IsPublic(pkgPath string) bool
- func IsValueEmptyColl(val r.Value) bool
- func IsValueNil(val r.Value) bool
- func IsValueZero(val r.Value) bool
- func IsZero(val interface{}) bool
- func Iter(count int) []struct{}
- func Kind(val interface{}) r.Kind
- func Len(val interface{}) int
- func NormNil(val interface{}) interface{}
- func OffsetFields(typ interface{}) map[uintptr][]r.StructField
- func SliceType(val interface{}) r.Type
- func TagIdent(tag string) string
- func Trawl(src, out interface{})
- func TrawlWith(src, out interface{}, fil Filter)
- func TypeDeepFields(typ r.Type) []r.StructField
- func TypeDeref(typ r.Type) r.Type
- func TypeElem(typ r.Type) r.Type
- func TypeFields(typ r.Type) []r.StructField
- func TypeKind(val r.Type) r.Kind
- func TypeOffsetFields(typ r.Type) map[uintptr][]r.StructField
- func ValidFunc(val interface{}) r.Value
- func ValidMap(val interface{}) r.Value
- func ValidPtr(val interface{}) r.Value
- func ValidPtrToKind(val interface{}, exp r.Kind) r.Value
- func ValidSlice(val interface{}) r.Value
- func ValidSliceOf(val interface{}, exp r.Type) r.Value
- func ValidSliceOfKind(val interface{}, exp r.Kind) r.Value
- func ValidStruct(val interface{}) r.Value
- func ValidTypeFunc(val interface{}) r.Type
- func ValidTypeMap(val interface{}) r.Type
- func ValidTypePtr(val interface{}) r.Type
- func ValidTypeSlice(val interface{}) r.Type
- func ValidTypeStruct(val interface{}) r.Type
- func ValidateFunc(val r.Value) r.Value
- func ValidateFuncIn(typ r.Type, params ...r.Type)
- func ValidateFuncNumIn(typ r.Type, exp int)
- func ValidateFuncNumOut(typ r.Type, exp int)
- func ValidateFuncOut(typ r.Type, params ...r.Type)
- func ValidateMap(val r.Value) r.Value
- func ValidatePtr(val r.Value) r.Value
- func ValidatePtrToKind(val r.Value, exp r.Kind) r.Value
- func ValidateSlice(val r.Value) r.Value
- func ValidateSliceOf(val r.Value, exp r.Type) r.Value
- func ValidateSliceOfKind(val r.Value, exp r.Kind) r.Value
- func ValidateStruct(val r.Value) r.Value
- func ValidateTypeFunc(typ r.Type) r.Type
- func ValidateTypeKind(typ r.Type, exp r.Kind) r.Type
- func ValidateTypeMap(typ r.Type) r.Type
- func ValidateTypePtr(typ r.Type) r.Type
- func ValidateTypeSlice(typ r.Type) r.Type
- func ValidateTypeStruct(typ r.Type) r.Type
- func ValidateValueKind(val r.Value, exp r.Kind) r.Value
- func ValueAddr(val r.Value) r.Value
- func ValueDeref(val r.Value) r.Value
- func ValueLen(val r.Value) int
- func ValueType(val r.Value) r.Type
- func Walk(val r.Value, fil Filter, vis Visitor)
- func WalkFunc(val r.Value, fil Filter, vis VisitorFunc)
- func Zero(ptr interface{})
- type All
- type And
- type Appender
- type Both
- type Cache
- type Desc
- type Err
- type Filter
- type IfaceFilter
- type InvertSelf
- type Nop
- type Or
- type Path
- type Rev
- type Self
- type ShallowIfaceFilter
- type TagFilter
- type TypeFilter
- type Visitor
- type VisitorFunc
- type Walker
Constants ¶
const ( // Don't visit self or descendants. Being zero, this is the default. VisNone = 0b_0000_0000 // Visit self. VisSelf = 0b_0000_0001 // Visit descendants. VisDesc = 0b_0000_0010 // Visit both self and descendants. VisBoth = VisSelf | VisDesc // Same effect as `rf.VisBoth`. Provided for arithmetic. VisAll = 0b_1111_1111 )
Flags constituting the return value of `rf.Filter`. Unknown bits will be ignored.
Variables ¶
This section is empty.
Functions ¶
func DeepFields ¶ added in v0.4.0
func DeepFields(typ interface{}) []r.StructField
Shortcut for `rf.TypeDeepFields(rf.DerefType(typ))`.
func Deref ¶ added in v0.4.0
Shortcut for `rf.ValueDeref(reflect.ValueOf(val))`. Returns the `reflect.Value` of the input, automatically dereferencing any outer pointers. If any outer pointers are nil, returns `reflect.Value{}`.
func DerefKind ¶
Shortcut for `rf.TypeKind(rf.DerefType(val))`. Returns the kind of the provided value, automatically dereferencing any outer pointer types until it finds a non-pointer type. If the input is nil, returns `reflect.Invalid`.
func DerefSlice ¶
Shortcut for `rf.DerefWithKind(val, reflect.Slice)`.
func DerefStruct ¶
Shortcut for `rf.DerefWithKind(val, reflect.Struct)`.
func DerefType ¶
Same as `reflect.TypeOf`, but dereferences the type, allowing to pass a nil pointer, which doesn't allocate. The following expressions both produce the type of `time.Time`, but the second one is cheaper:
rf.DerefType(time.Time{}) // Allocates.
rf.DerefType((*time.Time)(nil)) // Doesn't allocate.
func DerefWithKind ¶ added in v0.4.0
Ensures that the given value either directly or indirectly (through any number of arbitrarily-nested pointer types) contains a type of the provided kind, and returns its dereferenced value. If any intermediary pointer is nil, the returned value is invalid.
func ElemType ¶
Shortcut for `rf.TypeElem(reflect.TypeOf(val))`. Returns the element type of the given value, automatically dereferencing pointer AND slice types, until it finds the first non-pointer, non-slice type. If the input is nil, returns nil.
func Fields ¶ added in v0.2.2
func Fields(typ interface{}) []r.StructField
Shortcut for `rf.TypeFields(rf.DerefType(typ))`.
func FuncName ¶
func FuncName(val interface{}) string
Returns the name of a given function, if possible. Returns "" for nil.
func Interface ¶ added in v0.4.0
Like `reflect.Value.Interface`, but returns nil when value is invalid, and attempts to take an address by calling `rf.ValueAddr`, which is sometimes more efficient. Calling `reflect.Value.Interface` on a non-address makes a heap copy of the underlying value, while indirection can avoid that cost.
func IsColl ¶
func IsColl(val interface{}) bool
True if the kind of the provided value is a collection. See `rf.IsKindColl` for further details. Note that this follows `reflect.Value.Len` rather than the built-in `len` in that pointers to arrays are not considered to be collections.
func IsEmbed ¶
func IsEmbed(val r.StructField) bool
True if the given field represents an embedded non-pointer struct type. False if it's embedded by pointer.
func IsEmptyColl ¶
func IsEmptyColl(val interface{}) bool
True if the input belongs to one of the kinds "reflect" considers collections (see `rf.IsKindColl`), and has the length of zero. If the input is a non-nil interface that describes a nil collection, such as `([]string)(nil)`, this returns true. If the input is a nil interface, this returns false. Doesn't automatically dereference the input.
func IsKindColl ¶
True for the kinds "reflect" considers collections: array, chan, map, slice, or string. These are the kinds for which it's safe to call `reflect.Value.Len` without panicking.
func IsKindNilable ¶
True for kinds on which it's safe to call `reflect.Value.IsNil`.
func IsNil ¶
func IsNil(val interface{}) bool
True if the input is a nil interface or a non-nil interface containing a nil value. See `rf.IsValueNil`.
func IsPublic ¶
True if the input string is empty. Allows to clarify reflection code that checks the public/private status of struct fields and type methods. Examples (oversimplified):
rf.IsPublic(reflect.StructField{}.PkgPath)
rf.IsPublic(reflect.Method{}.PkgPath)
func IsValueEmptyColl ¶
Variant of `rf.IsEmpty` that takes a `reflect.Value` as input. See `rf.IsEmpty` for the documentation.
func IsValueNil ¶
True if the input is invalid or contains a nilable value that is nil. Automatically dereferences pointers, returning true for a non-nil pointer to a nil value.
func IsValueZero ¶
True if the input is nil (as defined by `rf.IsValueNil`) or a zero value of its type. Automatically dereferences pointers.
func IsZero ¶
func IsZero(val interface{}) bool
Shortcut for `rf.IsValueZero(reflect.ValueOf(val))`. True if the input is nil or a zero value of its type. Automatically dereferences the input; an arbitrarily-nested non-nil pointer to a zero value is considered zero.
func Iter ¶
func Iter(count int) []struct{}
Zero-cost integer iterator. Usage:
for range rf.Iter(N) { ... }
for i := range rf.Iter(N) { ... }
Because `struct{}` is zero-sized, `[]struct{}` is backed by "zerobase" (see "runtime/malloc.go") and does not allocate. This should perform about as well as a "normal" counted loop.
This is not reflection related, but exported because it's used internally a lot.
func Kind ¶
Same as `reflect.TypeOf(val).Kind()`, but returns `reflect.Invalid` for a nil input, instead of panicking. Doesn't automatically dereference the input.
func Len ¶ added in v0.3.0
func Len(val interface{}) int
Shortcut for `rf.ValueLen(rf.Deref(val))`. Returns the length of the given value, if possible. If not, returns 0. Automatically dereferences the input.
func NormNil ¶
func NormNil(val interface{}) interface{}
Short for "normalize nil". If the input is a non-nil interface whose underlying value is nil, this normalizes it, returning a nil interface. Otherwise this returns the input as-is.
func OffsetFields ¶ added in v0.4.0
func OffsetFields(typ interface{}) map[uintptr][]r.StructField
Shortcut for `rf.TypeOffsetFields(rf.DerefType(typ))`.
func SliceType ¶
Shortcut for `reflect.SliceOf(DerefType(val))`. The following expressions are all equivalent:
reflect.SliceOf(reflect.TypeOf(``)) reflect.SliceOf(reflect.TypeOf((*string)(nil)).Elem()) rf.SliceType(``) rf.SliceType((*string)(nil))
func TagIdent ¶
Takes a struct field tag and returns its identifier part, following the "encoding/json" conventions. Ident "-" is converted to "". Usage:
ident := rf.TagIdent(someField.Tag.Get(`json`)) ident := rf.TagIdent(someField.Tag.Get(`db`))
Rules:
json:"ident" -> "ident" json:"ident,<extra>" -> "ident" json:"-" -> "" json:"-,<extra>" -> ""
func Trawl ¶
func Trawl(src, out interface{})
Shortcut for `rf.TrawlWith` without an additional filter. Takes an arbitrary source value and a pointer to an output slice. Walks the source value, appending all non-zero values of the matching type to the given slice.
func TrawlWith ¶
func TrawlWith(src, out interface{}, fil Filter)
Shortcut for using `rf.Appender` and `rf.Walk` to trawl the provided "source" value to collect all non-zero values of a specific type into an "output" slice. The source value may be of arbitrary type. The output must be a non-nil pointer to a slice. The additional filter is optional.
func TypeDeepFields ¶ added in v0.4.0
func TypeDeepFields(typ r.Type) []r.StructField
Takes a struct type and returns a slice of its fields, with support for embedded structs. Structs embedded by value (not by pointer) are considered parts of the enclosing struct, rather than fields in their own right, and their fields are included into this function's output. This is NOT equivalent to the fields you would get by iterating over `reflect.Type.NumField`. Not only because it includes the fields of value-embedded structs, but also because it adjusts `reflect.StructField.Index` and `reflect.StructField.Offset` specifically for the given ancestor type. In particular, `reflect.StructField.Offset` of deeply-nested fields is exactly equivalent to the output of `unsafe.Offsetof` for the same parent type and field, which is NOT what you would normally get from the "reflect" package.
For comparison. Normally when using `reflect.Type.FieldByIndex`, the returned fields have both their offset and their index relative to their most immediate parent, rather than the given ancestor. But it's also inconsistent. When using `reflect.Type.FieldByName`, the returned fields have their index relative to the ancestor, but their offset is still relative to their most immediate parent.
This function actually fixes all that. It gives you fields where offsets AND indexes are all relative to the ancestor.
Like `rf.TypeFields`, this caches and reuses the resulting slice for all future calls for any given type. The resulting slice or its elements must not be mutated.
func TypeDeref ¶
Returns the element type of the provided type, automatically dereferencing pointer types. If the input is nil, returns nil.
func TypeElem ¶
Returns the element type of the provided type, automatically dereferencing pointer AND slice types, until it finds the first non-pointer, non-slice type. If the input is nil, returns nil.
func TypeFields ¶ added in v0.2.2
func TypeFields(typ r.Type) []r.StructField
Takes a struct type and returns a shallow slice of its fields, similar to what you would get by iterating over `reflect.Type.NumField`. For any given type, caches and reuses the resulting slice for all future calls. The resulting slice or its elements must not be mutated. Note: because this doesn't support embedded structs, for most use cases `rf.TypeDeepFields` is more appropriate.
func TypeKind ¶
Same as `reflect.Type.Kind(val)`, but returns `reflect.Invalid` for a nil input, instead of panicking. Doesn't automatically dereference the input.
func TypeOffsetFields ¶ added in v0.4.0
func TypeOffsetFields(typ r.Type) map[uintptr][]r.StructField
Takes a struct type and returns a mapping of field offsets to fields. Offsets correspond to `unsafe.Offsetof`. The map is built from `rf.TypeDeepFields`, which treats structs embedded by value (not by pointer) as parts of the enclosing struct, including their fields into the output, and adjusts field offsets for compatibility with `unsafe.Offsetof`. Offsets may correspond to multiple fields because fields may be zero-sized. Each included slice has at least one field. Caches and reuses the resulting map for all future calls for any given type. The map or anything contained within must not be mutated.
func ValidPtrToKind ¶
Shortcut for `rf.ValidatePtrToKind(reflect.ValueOf(val))`. Converts the input to `reflect.Value`, ensures that it's a non-nil pointer where the inner type has the required kind, and returns the resulting `reflect.Value`.
func ValidSlice ¶
Shortcut for `rf.ValidateSlice(reflect.ValueOf(val))`.
func ValidSliceOf ¶
Shortcut for `rf.ValidateSliceOf(reflect.ValueOf(val))`. Converts the input to `reflect.Value`, ensures that it's a slice with the required element type, and returns the resulting `reflect.Value`.
func ValidSliceOfKind ¶
Shortcut for `rf.ValidateSliceOfKind(reflect.ValueOf(val))`. Converts the input to `reflect.Value`, ensures that it's a slice where the element type has the required kind, and returns the resulting `reflect.Value`.
func ValidStruct ¶
Shortcut for `rf.ValidateStruct(reflect.ValueOf(val))`.
func ValidTypeFunc ¶
Shortcut for `rf.ValidateTypeFunc(reflect.TypeOf(val))`.
func ValidTypeMap ¶
Shortcut for `rf.ValidateTypeMap(reflect.TypeOf(val))`.
func ValidTypePtr ¶
Shortcut for `rf.ValidateTypePtr(reflect.TypeOf(val))`.
func ValidTypeSlice ¶
Shortcut for `rf.ValidateTypeSlice(reflect.TypeOf(val))`.
func ValidTypeStruct ¶
Shortcut for `rf.ValidateTypeStruct(reflect.TypeOf(val))`.
func ValidateFunc ¶
Shortcut for `rf.ValidateValueKind(val, reflect.Func)`.
func ValidateFuncIn ¶
Takes a func type and ensures that its input parameters exactly match the count and types provided to this function, or panics with a descriptive error. Among the provided parameter types, nil serves as a wildcard that matches any type.
func ValidateFuncNumIn ¶
Takes a func type and ensures that it has the required count of input parameters, or panics with a descriptive error.
func ValidateFuncNumOut ¶
Takes a func type and ensures that it has the required count of output parameters, or panics with a descriptive error.
func ValidateFuncOut ¶
Takes a func type and ensures that its return parameters exactly match the count and types provided to this function, or panics with a descriptive error. Among the provided parameter types, nil serves as a wildcard that matches any type.
func ValidateMap ¶
Shortcut for `rf.ValidateValueKind(val, reflect.Map)`.
func ValidatePtr ¶
Similar to `rf.ValidateValueKind(val, reflect.Ptr)`, but also ensures that the pointer is non-nil.
func ValidatePtrToKind ¶
Ensures that the value is a non-nil pointer where the underlying type has the required kind, or panics with a descriptive error. Returns the same value, allowing shorter code. Supports pointers of any depth: `*T`, `**T`, etc. Known limitation: only the outermost pointer is required to be non-nil. Inner pointers may be nil.
func ValidateSlice ¶
Shortcut for `rf.ValidateValueKind(val, reflect.Slice)`.
func ValidateSliceOf ¶
Ensures that the value is a slice where the element type has the required type, or panics with a descriptive error. Returns the same value, allowing shorter code. Doesn't automatically dereference the input.
func ValidateSliceOfKind ¶
Ensures that the value is a slice where the element type has the required kind, or panics with a descriptive error. Returns the same value, allowing shorter code. Doesn't automatically dereference the input.
func ValidateStruct ¶
Shortcut for `rf.ValidateValueKind(val, reflect.Struct)`.
func ValidateTypeFunc ¶
Shortcut for `rf.ValidateTypeKind(typ, reflect.Func)`.
func ValidateTypeKind ¶
Ensures that the type has the required kind or panics with a descriptive error. Returns the same type, allowing shorter code.
func ValidateTypeMap ¶
Shortcut for `rf.ValidateTypeKind(typ, reflect.Map)`.
func ValidateTypePtr ¶
Shortcut for `rf.ValidateTypeKind(typ, reflect.Ptr)`.
func ValidateTypeSlice ¶
Shortcut for `rf.ValidateTypeKind(typ, reflect.Slice)`.
func ValidateTypeStruct ¶
Shortcut for `rf.ValidateTypeKind(typ, reflect.Struct)`.
func ValidateValueKind ¶
Ensures that the value has the required kind or panics with a descriptive error. Returns the same value, allowing shorter code.
func ValueAddr ¶ added in v0.4.0
If the value represents a non-pointer and its address can be taken, returns its address via `reflect.Value.Addr`. Otherwise returns the value as-is. Sometimes handy when taking an address is an optional optimization, such as before calling `reflect.Value.Interface`.
func ValueDeref ¶
Dereferences the provided value until it's no longer a pointer. If the input is a nil pointer or a pointer to a nil pointer (recursively), this returns `reflect.Value{}`.
func ValueLen ¶
If the provided value is a collection via `rf.IsColl`, returns the result of calling `reflect.Value.Len`. Otherwise returns 0. Doesn't automatically dereference the input.
func ValueType ¶
Same as `reflect.Value.Type` but "safe" to call on invalid value, in which case this will return nil. Should be used only when nil output type is acceptable.
func Walk ¶
Takes an arbitrary value and performs deep traversal, invoking the visitor for each node allowed by the filter. Internally, uses `rf.GetWalker` to get or create a walker specialized for this combination of type and filter. For each type+filter combination, `rf.GetWalker` generates a specialized walker, caching it for future calls. This approach allows MUCH more efficient walking.
Types ¶
type All ¶ added in v0.3.0
type All struct{}
Implementation of `rf.Filter` that always returns `rf.VisAll`.
type And ¶
type And [8]Filter
Implementation of `rf.Filter` that combines other filters, AND-ing their outputs via `&`. Nil elements are ignored. If all elements are nil, the output is automatically `VisNone`.
type Appender ¶
Implementation of `rf.Visitor` for collecting non-zero values of a single type into a slice. The inner value must be `reflect.Value` holding a slice. The value must be settable. Use `rf.AppenderFor` to instantiate this correctly.
func AppenderFor ¶
func AppenderFor(typ interface{}) Appender
Shortcut for making `rf.Appender`. The input must be a carrier of the element type, not the slice type.
func (Appender) Filter ¶
Returns a filter that allows to visit only values suitable to be elements of the slice held by the appender.
type Both ¶ added in v0.3.0
type Both struct{}
Implementation of `rf.Filter` that always returns `rf.VisBoth`.
type Cache ¶
Tiny shortcut for caching arbitrary structures keyed by `reflect.Type`. Any reflection-based code that involves walking arbitrary structs should use `rf.Cache` to "compile" a specialized structure optimized for that particular traversal, and reuse it for subsequent invocations.
type Desc ¶ added in v0.3.0
type Desc struct{}
Implementation of `rf.Filter` that always returns `rf.VisDesc`.
type Filter ¶
type Filter interface {
Visit(r.Type, r.StructField) byte
}
Tool for implementing efficient reflect-based deep walking. Determines if a particular node should be visited during a walk, and how. This package provides several filter implementations, such as filtering by type, by struct tag, or combining other filters.
The return value of `rf.Filter.Visit` is a combination of two optional flags: `rf.VisSelf` and `rf.VisDesc`. Flags are combined with bitwise OR. The following combinations are known:
return VisNone // Zero value / default. return VisSelf return VisDesc return VisSelf | VisDesc return VisBoth // Shortcut for the above.
If the flag `rf.VisDesc` is set, we attempt to generate an inner walker that visits the descendants of the current node, such as the elements of a slice, the fields of a struct, the value behind a pointer, or the value referenced by an interface. Otherwise, we don't attempt to generate an inner walker.
If the flag `rf.VisSelf` is set, we generate a walker that invokes `Visitor.Visit` on the current node. Otherwise the resulting walker will not visit the current node, and may possibly be nil.
For technical reasons, all implementations of this interface must be values rather than references. For example, filters provided by this package must be used as values rather than pointers. The following is the CORRECT way to construct filters:
var filter rf.Filter = rf.And{
TypeFilterFor((*string)(nil)),
rf.TagFilter{`json`, `fieldName`},
}
The following is the INCORRECT way to construct filters. Due to internal validation, this will cause panics at runtime:
var filter rf.Filter = &rf.And{
&rf.TypeFilter{rf.DerefType((*string)(nil))},
&rf.TagFilter{`json`, `fieldName`},
}
See also:
rf.Walker rf.Visitor rf.GetWalker rf.Walk
type IfaceFilter ¶ added in v0.3.0
Implementation of `rf.Filter` that allows to visit values whose types implement the given interface BY POINTER. If the type is nil, this won't visit anything. The type must represent an interface, otherwise this will panic. The visitor must explicitly take value address:
func visit(val r.Value, _ r.StructField) {
val.Addr().Interface().(SomeInterface).SomeMethod()
}
func IfaceFilterFor ¶ added in v0.3.3
func IfaceFilterFor(typ interface{}) IfaceFilter
Shortcut, same as `rf.IfaceFilter{rf.DerefType(typ)}`.
func (IfaceFilter) Visit ¶ added in v0.3.0
func (self IfaceFilter) Visit(typ r.Type, _ r.StructField) byte
Implement `rf.Filter`.
type InvertSelf ¶ added in v0.3.0
type InvertSelf [1]Filter
Implementation of `rf.Filter` that inverts the "self" bit of the inner filter, without changing the other flags. If the inner filter is nil, this always returns `rf.VisNone`.
func (InvertSelf) Visit ¶ added in v0.3.0
func (self InvertSelf) Visit(typ r.Type, field r.StructField) byte
Implement `rf.Filter`.
type Nop ¶
type Nop struct{}
No-op implementation of both `rf.Visitor` that does nothing upon visit.
type Or ¶
type Or [8]Filter
Implementation of `rf.Filter` that combines other filters, OR-ing their outputs via `|`. Nil elements are ignored. If all elements are nil, the output is automatically `VisNone`.
type Path ¶ added in v0.4.0
type Path []int
Alias of `[]int` (which is used for struct field paths such as `reflect.StructField.Index`) with some shortcuts relevant for efficient and correct walking of struct types.
func (*Path) Add ¶ added in v0.4.0
Appends elements to the path, returning a stack-allocatable value that can revert the path to the previous length by reslicing, keeping any capacity that was added by the append. Usage:
defer path.Add(field.Index).Reset()
type Rev ¶ added in v0.4.0
Returned by `(*rf.Path).Add`. Syntactic shortcut for appending to a path for the duration of a function, reverting it back at the end. Should be transient, stack-allocated, and basically free to use.
type Self ¶ added in v0.3.0
type Self struct{}
Implementation of `rf.Filter` that always returns `rf.VisSelf`.
type ShallowIfaceFilter ¶ added in v0.3.2
Like `IfaceFilter`, but visits either self or descendants, not both. In other words, once it finds a node that implements the given interface (by pointer), it allows to visit that node and stops there, without walking its descendants.
func ShallowIfaceFilterFor ¶ added in v0.3.3
func ShallowIfaceFilterFor(typ interface{}) ShallowIfaceFilter
Shortcut, same as `rf.ShallowIfaceFilter{rf.DerefType(typ)}`.
func (ShallowIfaceFilter) Visit ¶ added in v0.3.2
func (self ShallowIfaceFilter) Visit(typ r.Type, _ r.StructField) byte
Implement `rf.Filter`.
type TagFilter ¶
type TagFilter [2]string
Implementation of `rf.Filter` that allows to visit values whose struct tag has a specific tag with a specific value, such as tag "json" with value "-". It also allows to visit descendants.
type TypeFilter ¶
Implementation of `rf.Filter` that allows to visit values of this specific type. If the type is nil, this won't visit anything. The type may be either concrete or an interface. It also allows to visit descendants.
func TypeFilterFor ¶ added in v0.2.1
func TypeFilterFor(typ interface{}) TypeFilter
Shortcut, same as `rf.TypeFilter{rf.DerefType(typ)}`.
func (TypeFilter) Visit ¶ added in v0.3.0
func (self TypeFilter) Visit(typ r.Type, _ r.StructField) byte
Implement `rf.Filter`.
type Visitor ¶
type Visitor interface {
Visit(r.Value, r.StructField)
}
Used by `rf.Walker` and `rf.Walk` to visit certain nodes of the given value. A visitor can be an arbitrary value or a function; see `rf.VisitorFunc`.
type VisitorFunc ¶
type VisitorFunc func(r.Value, r.StructField)
Function type that implements `rf.Visitor`. Used by `rf.WalkFunc`. Converting a func to an interface value is alloc-free.
func (VisitorFunc) Visit ¶
func (self VisitorFunc) Visit(val r.Value, field r.StructField)
Implement `rf.Visitor` by calling itself.
type Walker ¶
Tool for implementing efficient reflect-based deep walking. The function `rf.GetWalker` generates a walker for a SPECIFIC combination of parent type and `rf.Filter`. The resulting walker is specialized for that combination, and walks its input precisely and efficiently.
For simplicity and efficiency reasons, walkers generated by this package don't additionally assert that the provided `reflect.Value` has the same type for which the walker is generated. When using `rf.Walk` or `rf.WalkFunc`, this is handled for you. Otherwise, it's your responsibility to pass a value of the same type. For simplicity, walkers also assume that the visitor is non-nil.
This package currently does NOT support walking into maps, for two reasons: unclear semantics and inefficiency. It's unclear if we should walk keys, values, or key-value pairs, and how that affects the rest of the walking API. Currently in Go 1.17, reflect-based map walking has horrible inefficiencies which can't be amortized by 3rd party code. It would be a massive performance footgun.
This package does support walking into interface values included into other structures, but at an efficiency loss. In general, our walking mechanism relies on statically determining what we should and shouldn't visit, which is possible only with static types. Using interfaces as dynamically-typed containers of unknown values defeats this design by forcing us to always visit each of them, and may produce significant slowdowns. However, while visiting each interface value is an unfortunate inefficiency, walking the value REFERENCED by an interface is as precise and efficient as with static types.
func GetWalker ¶
Returns an `rf.Walker` for the given type with the given filter. Uses caching to avoid generating a walker more than once. Future calls with the same inputs will return the same walker instance. Returns nil if for this combination of type and filter, nothing will be visited. A nil filter is equivalent to a filter that always returns false, resulting in a nil walker.