Package set is a small wrapper around the official reflect package that facilitates loose type conversion and assignment into native Go types.
Package set
is a performant reflect wrapper supporting loose type conversion, struct mapping and population, and slice building.
The godoc
documentation has detailed information and many examples but following is the high-level view.
Type coercion allows assignment from loosey-goosey sources -- for example incoming string data -- to strongly typed Go types.
var t T // T is a target data type, t is a variable of that type.
var s S // S is a source data type, s is a variable of that type.
set.V(&t).To(s) // Sets s into t with a "best effort" approach.
set.Value
has two methods, Fill
and FillByTag
, that use the set.Getter
interface as the provider for data to populate a struct and its hierarchy.
For convenience:
set.GetterFunc
allows plain functions to be used as a set.Getter
similar to http.HandlerFunc
.set.MapGetter
allows either map[string]T
or map[interface{}]T
to be used as a set.Getter
.set.Mapper
is a powerful and highly configurable struct mapping facility.
A mapper will traverse a struct hiearchy and create a 1:1
mapping of friendly names
to traversal information
. The friendly names can then be used to target associated fields within a struct value and its hierarchy.
Example usages of a mapper are to map CSV column headings to struct fields, database column names to struct fields, or creating a generic struct copier to marshal structs across different domains or boundaries in your application architecture.
set.Mapper
contains several configuration fields that can be used to fully customize the generated friendly names
:
VendorName
, Vendor_Name
, Vendor.Name
, vendor_name
, etc.db
tag values can have higher precedence than json
tagsOnce a set.Mapper
(described above) is created it can return BoundMapping
or PreparedMapping
types that are bound to Go structs. In turn BoundMapping
and PreparedMapping
provide performant access to the bound data via the friendly names generated by the mapper.
A BoundMapping
provides an adhoc access to struct fields; each method takes the mapped name of the field to access. An example use case for BoundMapping
is populating data when some of the data may be missing and you may not set data for every possible mapped field.
A PreparedMapping
is similar to a prepared SQL statement and the access plan must be set with a call to its Plan
method. An example use case for PreparedMapping
is populating CSV data or database rows where every row is guaranteed to access the same fields in the same order.
Package reflect
is always slower than code not using reflect
. A considerable effort has been spent designing and implementing this package to reduce reflect overhead.
reflect
data is generally only gathered once (via reflect.TypeOf, reflect.ValueOf) when first encountering a type. This data is cached and retrieved from cache on further encounters with repeated types.reflect
. This strategy is heavily used during type coercion.Rebind
method. Rebind
will swap a "bound" Go type with a new incoming instance without making additional expensive calls into reflect
. The outgoing and incoming types must be compatible but this is the expected usage in tight loops building slices of data.Additionally this package attempts to be low allocation so as not to overwhelm the garbage collector.
I am making a very concerted effort to break the API as little as possible while adding features or fixing bugs. However this software is currently in a pre-1.0.0 version and breaking changes are allowed under standard semver. As the API approaches a stable 1.0.0 release I will list any such breaking changes here and they will always be signaled by a bump in minor version.
0.4.0 ⭢ 0.5.0
README-0.4.0-to-0.5.0.md outlines many of the package changes, reasoning, and benchmarks
Remove erroneous documentation for Value.To
method.
The documentation indicated that when Dst and Src are both pointers with same level of indirection that direct assignment was performed. This is not true. The Value type uses the values at the end of pointers and pointer chains and therefore does not perform direct assignment of pointer values.
0.3.0 ⭢ 0.4.0
set.Mapper has new field TaggedFieldsOnly. TaggedFieldsOnly=false
means no change in behavior. TaggedFieldsOnly=true
means set.Mapper only maps exported fields with struct tags.
0.2.3 ⭢ 0.3.0
set.BoundMapping.Assignables has a second argument allowing you to pre-allocate the slice that is returned; you can also set it to nil
to keep current behavior.