Fix structtags

This commit is contained in:
Fedor Korotkiy 2021-04-01 16:40:15 +03:00
parent 8ee0f793b5
commit e7909f0857
3 changed files with 12 additions and 20 deletions

View file

@ -8,8 +8,9 @@
goos: linux goos: linux
goarch: amd64 goarch: amd64
pkg: gitlab.com/slon/shad-go/structtags pkg: gitlab.com/slon/shad-go/structtags
BenchmarkUnpacker/user-4 3064 362500 ns/op cpu: Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz
BenchmarkUnpacker/user+good+order-4 663 1799294 ns/op BenchmarkUnpacker/user-4 4269022 275.0 ns/op
BenchmarkUnpacker/user+good+order-4 732264 1481 ns/op
PASS PASS
``` ```

View file

@ -10,18 +10,11 @@ import (
"strings" "strings"
) )
// Функция Unpack присваивает значения параметров из url query в поля переданной структуры.
// Для этого сначала в первом цикле создается map,
// где ключи -- названия параметров из url query,
// а значения -- "ссылки" на соответствующие поля структуры.
// В следующем цикле поля структуры заполняются соответствующими
// значениями из url query.
func Unpack(req *http.Request, ptr interface{}) error { func Unpack(req *http.Request, ptr interface{}) error {
if err := req.ParseForm(); err != nil { if err := req.ParseForm(); err != nil {
return err return err
} }
fields := make(map[string]reflect.Value) fields := make(map[string]reflect.Value)
v := reflect.ValueOf(ptr).Elem() v := reflect.ValueOf(ptr).Elem()
for i := 0; i < v.NumField(); i++ { for i := 0; i < v.NumField(); i++ {
@ -33,11 +26,13 @@ func Unpack(req *http.Request, ptr interface{}) error {
} }
fields[name] = v.Field(i) fields[name] = v.Field(i)
} }
for name, values := range req.Form { for name, values := range req.Form {
f := fields[name] f, ok := fields[name]
if !f.IsValid() { if !ok {
continue continue
} }
for _, value := range values { for _, value := range values {
if f.Kind() == reflect.Slice { if f.Kind() == reflect.Slice {
elem := reflect.New(f.Type().Elem()).Elem() elem := reflect.New(f.Type().Elem()).Elem()

View file

@ -139,19 +139,15 @@ func BenchmarkUnpacker(b *testing.B) {
b.Run("user", func(b *testing.B) { b.Run("user", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
for j := 0; j < 1000; j++ { _ = Unpack(userRequest, user)
_ = Unpack(userRequest, user)
}
} }
}) })
b.Run("user+good+order", func(b *testing.B) { b.Run("user+good+order", func(b *testing.B) {
for i := 0; i < b.N; i++ { for i := 0; i < b.N; i++ {
for j := 0; j < 1000; j++ { _ = Unpack(userRequest, user)
_ = Unpack(userRequest, user) _ = Unpack(goodRequest, good)
_ = Unpack(goodRequest, good) _ = Unpack(orderRequest, order)
_ = Unpack(orderRequest, order)
}
} }
}) })
} }