func (me *boundMapping) Fields(fields []string, rv []interface{}) ([]interface{}, error) {
	if !me.value.CanWrite {
		return nil, errors.Errorf("Value in BoundMapping is not writable; pass the address of your destination value when binding.")
	}
	if rv == nil {
		rv = make([]interface{}, len(fields))
	}
	for fieldnum, name := range fields {
		indeces := me.mapping.Get(name)
		if len(indeces) == 0 {
			return nil, errors.Errorf("No mapping for field [%v]", name)
		}
		v := me.value.WriteValue
		for k, size := 0, len(indeces); k < size; k++ {
			n := indeces[k]  
			if k < size-1 {
				v, _ = Writable(v.Field(n))
			} else {
				rv[fieldnum] = v.Field(n).Interface()
			}
		}
	}
	return rv, nil
}
Fields returns a slice of interfaces by field names where each element is the field value.

The second argument, if non-nil, will be the first return value.  In other words pre-allocating
rv will cut down on memory allocations.  It is assumed that if rv is non-nil that len(fields) == len(rv)
and the lengths are not checked, meaning your program might panic if rv is not the correct length.

During traversal this method will instantiate struct fields that are themselves structs.

An example use-case would be obtaining a slice of query arguments by column name during
database queries.
package set
import (
	"fmt"
	"reflect"
	"sort"
	"strings"
	"sync"
	"time"
	"github.com/nofeaturesonlybugs/errors"
)
var mapperTreatAsScalar = map[reflect.Type]struct{}{
	reflect.TypeOf(time.Time{}):  {},
	reflect.TypeOf(&time.Time{}): {},
}
type Mapping struct {
	Keys []string
	Indeces map[string][]int
	StructFields map[string]reflect.StructField
}
type Mapper struct {
	Ignored TypeList
	Elevated TypeList
	TreatAsScalar TypeList
	Tags []string
	Join string
	Transform func(string) string
	known sync.Map
}
type BoundMapping interface {
	Assignables(fields []string, rv []interface{}) ([]interface{}, error)
	Copy() BoundMapping
	Err() error
	Field(field string) (*Value, error)
	Fields(fields []string, rv []interface{}) ([]interface{}, error)
	Rebind(I interface{})
	Set(field string, value interface{}) error
}
var DefaultMapper = &Mapper{
	Join: "_",
}
func (me *Mapper) Bind(I interface{}) BoundMapping {
	var v *Value
	if tv, ok := I.(*Value); ok {
		v = tv
	} else {
		v = V(I)
	}
	rv := newBoundMapping(v, me.Map(v))
	return rv
}
func (me *Mapper) Map(T interface{}) *Mapping {
	var typeInfo TypeInfo
	switch tt := T.(type) {
	case *Value:
		typeInfo = tt.TypeInfo
	case reflect.Type:
		typeInfo = TypeCache.StatType(tt)
	default:
		typeInfo = TypeCache.Stat(T)
	}
	if rv, ok := me.known.Load(typeInfo.Type); ok {
		return rv.(*Mapping)
	}
	rv := &Mapping{
		Keys:         []string{},
		Indeces:      map[string][]int{},
		StructFields: map[string]reflect.StructField{},
	}
	var scan func(typeInfo TypeInfo, indeces []int, prefix string)
	scan = func(typeInfo TypeInfo, indeces []int, prefix string) {
		for k, field := range typeInfo.StructFields {
			if field.PkgPath != "" {
				continue
			}
			fieldTypeInfo := TypeCache.StatType(field.Type)
			if me.Ignored.Has(fieldTypeInfo.Type) {
				continue
			}
			name := ""
			if !me.Elevated.Has(fieldTypeInfo.Type) {
				for _, tagName := range append(me.Tags, "") {
					if tagValue, ok := field.Tag.Lookup(tagName); ok {
						name = tagValue
						break
					} else if tagName == "" {
						name = field.Name
						if me.Transform != nil {
							name = me.Transform(name)
						}
						break
					}
				}
			}
			if prefix != "" && name != "" {
				name = prefix + me.Join + name
			} else if prefix != "" {
				name = prefix
			}
			nameIndeces := append(indeces, k)
			if _, ok := mapperTreatAsScalar[fieldTypeInfo.Type]; ok {
				rv.Keys, rv.Indeces[name], rv.StructFields[name] = append(rv.Keys, name), nameIndeces, field
			} else if _, ok = me.TreatAsScalar[fieldTypeInfo.Type]; ok {
				rv.Keys, rv.Indeces[name], rv.StructFields[name] = append(rv.Keys, name), nameIndeces, field
			} else if fieldTypeInfo.IsStruct {
				scan(fieldTypeInfo, nameIndeces, name)
			} else if fieldTypeInfo.IsScalar {
				rv.Keys, rv.Indeces[name], rv.StructFields[name] = append(rv.Keys, name), nameIndeces, field
			}
		}
	}
	scan(typeInfo, []int{}, "")
	me.known.Store(typeInfo.Type, rv)
	return rv
}
func (me *Mapping) Copy() *Mapping {
	rv := &Mapping{
		Keys:         append([]string{}, me.Keys...),
		Indeces:      map[string][]int{},
		StructFields: map[string]reflect.StructField{},
	}
	for _, key := range me.Keys {
		rv.Indeces[key] = append([]int{}, me.Indeces[key]...)
		rv.StructFields[key] = me.StructFields[key]
	}
	return rv
}
func (me *Mapping) Get(key string) []int {
	v, _ := me.Lookup(key)
	return v
}
func (me *Mapping) Lookup(key string) (indeces []int, ok bool) {
	if me == nil || me.Indeces == nil {
		return nil, false
	}
	indeces, ok = me.Indeces[key]
	return indeces, ok
}
func (me *Mapping) String() string {
	if me == nil {
		return ""
	}
	parts := []string{}
	for str, indeces := range me.Indeces {
		parts = append(parts, fmt.Sprintf("%v\t\t%v", indeces, str))
	}
	sort.Strings(parts)
	return strings.Join(parts, "\n")
}
type boundMapping struct {
	value *Value
	err   error
	mapping *Mapping
}
func newBoundMapping(value *Value, mapping *Mapping) *boundMapping {
	return &boundMapping{
		value:   value,
		mapping: mapping,
	}
}
func (me *boundMapping) Assignables(fields []string, rv []interface{}) ([]interface{}, error) {
	if !me.value.CanWrite {
		return nil, errors.Errorf("Value in BoundMapping is not writable; pass the address of your destination value when binding.")
	}
	if rv == nil {
		rv = make([]interface{}, len(fields))
	}
	for fieldnum, name := range fields {
		indeces := me.mapping.Get(name)
		if len(indeces) == 0 {
			return nil, errors.Errorf("No mapping for field [%v]", name)
		}
		v := me.value.WriteValue
		for k, size := 0, len(indeces); k < size; k++ {
			n := indeces[k]  
			if k < size-1 {
				v, _ = Writable(v.Field(n))
			} else {
				rv[fieldnum] = v.Field(n).Addr().Interface()
			}
		}
	}
	return rv, nil
}
func (me *boundMapping) Copy() BoundMapping {
	return &boundMapping{
		value: me.value.Copy(),
		err:   me.err,
		mapping: me.mapping,
	}
}
func (me *boundMapping) Err() error {
	return me.err
}
func (me *boundMapping) Field(field string) (*Value, error) {
	var v reflect.Value
	var err error
	if v, err = me.value.FieldByIndex(me.mapping.Get(field)); err != nil {
		return nil, errors.Go(err)
	}
	return V(v), nil
}