func (e *Encoder) Values(v interface{}) (url.Values, error) {
	val := reflect.ValueOf(v)
	for val.Kind() == reflect.Ptr {
		if val.IsNil() {
			return nil, errors.Errorf("expects struct input, got %v", val.Kind())
		}
		val = val.Elem()
	}
	switch val.Kind() {
	case reflect.Invalid:
		return nil, errors.Errorf("expects struct input, got %v", val.Kind())
	case reflect.Struct:
		enc := e.dataPool.Get().(*encoder)
		enc.values = make(url.Values)
		err := enc.encodeStruct(val, enc.values, nil)
		if err != nil {
			return nil, err
		}
		values := enc.values
		e.dataPool.Put(enc)
		return values, nil
	default:
		return nil, errors.Errorf("expects struct input, got %v", val.Kind())
	}
}
Values encodes a struct into url.Values
v must be struct data type
package qs
import (
	"github.com/pkg/errors"
	"net/url"
	"reflect"
	"strings"
	"sync"
	"time"
)
const (
	tagOmitEmpty = "omitempty"
)
var (
	timeType    = reflect.TypeOf(time.Time{})
	encoderType = reflect.TypeOf(new(QueryParamEncoder)).Elem()
	zeroerType  = reflect.TypeOf(new(Zeroer)).Elem()
)
type EncoderOption func(encoder *Encoder)
type Encoder struct {
	tagAlias string
	cache    *cacheStore
	dataPool *sync.Pool
}
type encoder struct {
	e      *Encoder
	values url.Values
	tags   [][]byte
	scope  []byte
}
func WithTagAlias(tagAlias string) EncoderOption {
	return func(encoder *Encoder) {
		encoder.tagAlias = tagAlias
	}
}
func NewEncoder(options ...EncoderOption) *Encoder {
	e := &Encoder{
		tagAlias: "qs",
	}
	for _, opt := range options {
		opt(e)
	}
	e.cache = newCacheStore()
	e.dataPool = &sync.Pool{New: func() interface{} {
		tagSize := 5
		tags := make([][]byte, 0, tagSize)
		for i := 0; i < tagSize; i++ {
			tags = append(tags, make([]byte, 0, 56))
		}
		return &encoder{
			e:     e,
			tags:  tags,
			scope: make([]byte, 0, 64),
		}
	}}
	return e
}