From aeba465afbdb3c6c1e528cc2e201170f98166499 Mon Sep 17 00:00:00 2001 From: frank <8756012@qq.com> Date: Tue, 26 Jan 2021 14:30:50 +0800 Subject: [PATCH 1/7] BindDefaultValue --- value_types.go | 44 ++++++++++++++++ values_default.go | 112 +++++++++++++++++++++++++++++++++++++++++ values_default_test.go | 44 ++++++++++++++++ 3 files changed, 200 insertions(+) create mode 100644 value_types.go create mode 100644 values_default.go create mode 100644 values_default_test.go diff --git a/value_types.go b/value_types.go new file mode 100644 index 0000000..33d5ef1 --- /dev/null +++ b/value_types.go @@ -0,0 +1,44 @@ +package mapper + +import ( + "reflect" + "strconv" + "strings" + "time" +) + +func strFunc(str string) reflect.Value { + return reflect.ValueOf(str) +} + +func int64Func(str string) reflect.Value { + r, _ := strconv.ParseInt(str, 10, 64) + return reflect.ValueOf(r) +} + +func boolFunc(str string) reflect.Value { + b, _ := strconv.ParseBool(str) + return reflect.ValueOf(b) +} + +func float64Func(str string) reflect.Value { + r, _ := strconv.ParseFloat(str, 64) + return reflect.ValueOf(r) +} + +var defaultTimeLayout = "2006-01-02 15:04:05" + +func SetDefaultTimeLayout(layout string) { + defaultTimeLayout = layout +} + +func dateTimeFunc(str string) reflect.Value { + s := strings.Split(str, ";") + var t time.Time + if len(s) == 1 { + t, _ = time.ParseInLocation(defaultTimeLayout, str, time.Local) + } else if len(s) == 2 { + t, _ = time.ParseInLocation(s[1], s[0], time.Local) + } + return reflect.ValueOf(t) +} diff --git a/values_default.go b/values_default.go new file mode 100644 index 0000000..7750f3d --- /dev/null +++ b/values_default.go @@ -0,0 +1,112 @@ +package mapper + +import ( + "log" + "reflect" + "sync" + "time" +) + +type DefaultInitValue interface { + Default() reflect.Value +} + +type DefaultValueFunc func(str string) reflect.Value + +var regMap map[reflect.Type]DefaultValueFunc +var mux sync.RWMutex + +func RegisterDefaultValue(t reflect.Type, f DefaultValueFunc) { + mux.Lock() + defer mux.Unlock() + regMap[t] = f +} + +func init() { + regMap = make(map[reflect.Type]DefaultValueFunc) + RegisterDefaultValue(reflect.TypeOf(time.Time{}), dateTimeFunc) +} +func getFunc(k reflect.Type) DefaultValueFunc { + mux.RLock() + defer mux.RUnlock() + return regMap[k] +} +func bindValue(v reflect.Value, tag string) { + t := v.Type() + if t.Kind() == reflect.Ptr { + log.Println(t) + t = v.Elem().Type() + } + + if implDefaultInitValue(t) { + tv := v.Interface().(DefaultInitValue).Default() + if tv.Kind() == reflect.Struct && tv.Type() == t { + if v.Type().Kind() == reflect.Ptr { + v.Elem().Set(tv) + } else { + v.Set(tv) + } + return + } + } + if t.Kind() == reflect.Struct { + for i := 0; i < t.NumField(); i++ { + if v.Type().Kind() == reflect.Ptr { + if !checkSampleValue(v.Elem().Field(i), v.Elem().Type().Field(i), tag) { + bindValue(v.Elem().Field(i), tag) + } + } else { + if !checkSampleValue(v.Field(i), v.Type().Field(i), tag) { + bindValue(v.Field(i), tag) + } + } + } + } +} + +func checkSampleValue(v reflect.Value, field reflect.StructField, tag string) (ok bool) { + if tagValue, ok := field.Tag.Lookup(tag); ok { + if f := getFunc(v.Type()); f != nil { + if tv := f(tagValue); tv.Type() == v.Type() { + v.Set(tv) + ok = true + } + } else { + switch v.Kind() { + case reflect.String: + v.Set(strFunc(tagValue)) + ok = true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v.SetInt(int64Func(tagValue).Int()) + ok = true + case reflect.Bool: + v.SetBool(boolFunc(tagValue).Bool()) + ok = true + case reflect.Float32, reflect.Float64: + v.SetFloat(float64Func(tagValue).Float()) + ok = true + } + } + } + return +} + +func implDefaultInitValue(t reflect.Type) bool { + if t.Kind() == reflect.Ptr { + return t.Elem().Implements(reflect.TypeOf((*DefaultInitValue)(nil)).Elem()) + } else { + return t.Implements(reflect.TypeOf((*DefaultInitValue)(nil)).Elem()) + } +} +func defaultTag(tags ...string) string { + if len(tags) > 0 { + return tags[0] + } else { + return "d" + } +} + +//default tagKey d +func BindDefaultValue(target interface{}, tags ...string) { + bindValue(reflect.ValueOf(target), defaultTag(tags...)) +} diff --git a/values_default_test.go b/values_default_test.go new file mode 100644 index 0000000..464cd50 --- /dev/null +++ b/values_default_test.go @@ -0,0 +1,44 @@ +package mapper + +import ( + "log" + "reflect" + "testing" + "time" +) + +func init() { + log.SetFlags(log.Lshortfile | log.LstdFlags) +} + +func (s Info) Default() reflect.Value { + return reflect.ValueOf(Info{Name: "test name"}) +} + +//for test not same struct +type Info2 struct { + Ext string `d:"aaa"` + Name string `d:"123"` +} +type Info struct { + Ext string `d:"aaa"` + Name string `d:"123"` +} +type ShowInfo struct { + Name string `d:"name"` + Info + CreateTime time.Time `d:"2020-01-02 03:04:01"` +} + +func TestBindDefaultValue(t *testing.T) { + var s ShowInfo + BindDefaultValue(&s) + log.Printf("%+v", s) +} + +func BenchmarkBindDefaultValue(b *testing.B) { + var s ShowInfo + for i := 0; i < b.N; i++ { + BindDefaultValue(&s) + } +} From 6a9cb5010b99a34055b93dee9a829b084065ec7c Mon Sep 17 00:00:00 2001 From: frank <8756012@qq.com> Date: Sat, 30 Jan 2021 10:11:28 +0800 Subject: [PATCH 2/7] BindDefaultValue not default bind --- value_types.go | 26 +++++--- values_default.go | 140 ++++++++++++++++++++++++++++++----------- values_default_test.go | 46 ++++++++++---- 3 files changed, 156 insertions(+), 56 deletions(-) diff --git a/value_types.go b/value_types.go index 33d5ef1..8ed6c84 100644 --- a/value_types.go +++ b/value_types.go @@ -11,11 +11,27 @@ func strFunc(str string) reflect.Value { return reflect.ValueOf(str) } +//Support computing func int64Func(str string) reflect.Value { - r, _ := strconv.ParseInt(str, 10, 64) + //exp, err := parser.ParseExpr(str) + //if err == nil { + // fset := token.NewFileSet() + // _ = ast.Print(fset, exp) + //} + if strings.Contains(str, "*") { + ss := strings.Split(str, "*") + a, _ := strconv.ParseInt(strings.TrimSpace(ss[0]), 10, 64) + b, _ := strconv.ParseInt(strings.TrimSpace(ss[1]), 10, 64) + return reflect.ValueOf(a * b) + } else { + r, _ := strconv.ParseInt(str, 10, 64) + return reflect.ValueOf(r) + } +} +func uint64Func(str string) reflect.Value { + r, _ := strconv.ParseUint(str, 10, 64) return reflect.ValueOf(r) } - func boolFunc(str string) reflect.Value { b, _ := strconv.ParseBool(str) return reflect.ValueOf(b) @@ -26,12 +42,6 @@ func float64Func(str string) reflect.Value { return reflect.ValueOf(r) } -var defaultTimeLayout = "2006-01-02 15:04:05" - -func SetDefaultTimeLayout(layout string) { - defaultTimeLayout = layout -} - func dateTimeFunc(str string) reflect.Value { s := strings.Split(str, ";") var t time.Time diff --git a/values_default.go b/values_default.go index 7750f3d..bc9bc3f 100644 --- a/values_default.go +++ b/values_default.go @@ -11,80 +11,147 @@ type DefaultInitValue interface { Default() reflect.Value } +var ( + _defaultTag = "default" + _notDefaultTag = "-" +) +var defaultTimeLayout = "2006-01-02 15:04:05" + +func SetDefaultTimeLayout(layout string) { + mux.Lock() + defer mux.Unlock() + defaultTimeLayout = layout +} +func SetDefaultTag(tag string) { + mux.Lock() + defer mux.Unlock() + _defaultTag = tag +} + type DefaultValueFunc func(str string) reflect.Value -var regMap map[reflect.Type]DefaultValueFunc +var regTypeFuncMap map[reflect.Type]DefaultValueFunc +var regKindFuncMap map[reflect.Kind]DefaultValueFunc var mux sync.RWMutex -func RegisterDefaultValue(t reflect.Type, f DefaultValueFunc) { +func RegisterTypeForDefaultValue(t reflect.Type, f DefaultValueFunc) { mux.Lock() defer mux.Unlock() - regMap[t] = f + regTypeFuncMap[t] = f +} + +func RegisterKindForDefaultValue(t reflect.Kind, f DefaultValueFunc) { + mux.Lock() + defer mux.Unlock() + regKindFuncMap[t] = f } func init() { - regMap = make(map[reflect.Type]DefaultValueFunc) - RegisterDefaultValue(reflect.TypeOf(time.Time{}), dateTimeFunc) + regTypeFuncMap = make(map[reflect.Type]DefaultValueFunc) + regKindFuncMap = make(map[reflect.Kind]DefaultValueFunc) + RegisterTypeForDefaultValue(reflect.TypeOf(time.Time{}), dateTimeFunc) + + RegisterKindForDefaultValue(reflect.Int64, int64Func) + RegisterKindForDefaultValue(reflect.Uint64, uint64Func) +} +func getFuncByKind(k reflect.Kind) DefaultValueFunc { + mux.RLock() + defer mux.RUnlock() + return regKindFuncMap[k] } -func getFunc(k reflect.Type) DefaultValueFunc { +func getFuncByType(k reflect.Type) DefaultValueFunc { mux.RLock() defer mux.RUnlock() - return regMap[k] + return regTypeFuncMap[k] } func bindValue(v reflect.Value, tag string) { + if v == ZeroValue || v.IsZero() { + return + } t := v.Type() if t.Kind() == reflect.Ptr { - log.Println(t) t = v.Elem().Type() } if implDefaultInitValue(t) { - tv := v.Interface().(DefaultInitValue).Default() - if tv.Kind() == reflect.Struct && tv.Type() == t { - if v.Type().Kind() == reflect.Ptr { + dv, _ := v.Interface().(DefaultInitValue) + //TODO 此处无法判断 指针类型带来的接口实现 会造成 default 执行报错 + tv := dv.Default() + if v.Type().Kind() == reflect.Ptr { + if tv.Type() == t { v.Elem().Set(tv) + return } else { + if filed, ok := v.Elem().Type().FieldByName(tv.Type().Name()); ok && canDefaultBind(filed, tag) { + v.Elem().FieldByName(tv.Type().Name()).Set(tv) + } + } + } else { + if tv.Type() == t { v.Set(tv) + return + } else { + log.Println(tv.Type()) } - return } + } if t.Kind() == reflect.Struct { for i := 0; i < t.NumField(); i++ { if v.Type().Kind() == reflect.Ptr { - if !checkSampleValue(v.Elem().Field(i), v.Elem().Type().Field(i), tag) { + if v.Elem().Field(i).Kind() != reflect.Ptr && canDefaultBind(v.Elem().Type().Field(i), tag) && !checkSampleValue(v.Elem().Field(i), v.Elem().Type().Field(i), tag) { bindValue(v.Elem().Field(i), tag) } } else { - if !checkSampleValue(v.Field(i), v.Type().Field(i), tag) { + if v.Field(i).Kind() != reflect.Ptr && canDefaultBind(v.Type().Field(i), tag) && !checkSampleValue(v.Field(i), v.Type().Field(i), tag) { bindValue(v.Field(i), tag) } } } } } - +func canDefaultBind(field reflect.StructField, tag string) bool { + if t, ok := field.Tag.Lookup(tag); ok { + return t != _notDefaultTag + } + return true +} func checkSampleValue(v reflect.Value, field reflect.StructField, tag string) (ok bool) { if tagValue, ok := field.Tag.Lookup(tag); ok { - if f := getFunc(v.Type()); f != nil { - if tv := f(tagValue); tv.Type() == v.Type() { - v.Set(tv) - ok = true - } + if tagValue == _notDefaultTag { + return true } else { - switch v.Kind() { - case reflect.String: - v.Set(strFunc(tagValue)) - ok = true - case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: - v.SetInt(int64Func(tagValue).Int()) - ok = true - case reflect.Bool: - v.SetBool(boolFunc(tagValue).Bool()) - ok = true - case reflect.Float32, reflect.Float64: - v.SetFloat(float64Func(tagValue).Float()) - ok = true + if f := getFuncByType(v.Type()); f != nil { + if tv := f(tagValue); tv.Type() == v.Type() { + v.Set(tv) + ok = true + } + } else { + if f := getFuncByKind(v.Kind()); f != nil { + t := f(tagValue) + if v.Kind() == t.Kind() { + v.Set(t) + ok = true + } + } else { + switch v.Kind() { + case reflect.String: + v.Set(strFunc(tagValue)) + ok = true + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + v.SetInt(int64Func(tagValue).Int()) + ok = true + case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: + v.SetUint(uint64Func(tagValue).Uint()) + ok = true + case reflect.Bool: + v.SetBool(boolFunc(tagValue).Bool()) + ok = true + case reflect.Float32, reflect.Float64: + v.SetFloat(float64Func(tagValue).Float()) + ok = true + } + } } } } @@ -98,15 +165,18 @@ func implDefaultInitValue(t reflect.Type) bool { return t.Implements(reflect.TypeOf((*DefaultInitValue)(nil)).Elem()) } } + func defaultTag(tags ...string) string { if len(tags) > 0 { return tags[0] } else { - return "d" + return _defaultTag } } //default tagKey d func BindDefaultValue(target interface{}, tags ...string) { - bindValue(reflect.ValueOf(target), defaultTag(tags...)) + if reflect.TypeOf(target).Kind() == reflect.Ptr { + bindValue(reflect.ValueOf(target), defaultTag(tags...)) + } } diff --git a/values_default_test.go b/values_default_test.go index 464cd50..3a77b12 100644 --- a/values_default_test.go +++ b/values_default_test.go @@ -1,6 +1,7 @@ package mapper import ( + "encoding/json" "log" "reflect" "testing" @@ -8,37 +9,56 @@ import ( ) func init() { + SetDefaultTag("default") log.SetFlags(log.Lshortfile | log.LstdFlags) } -func (s Info) Default() reflect.Value { - return reflect.ValueOf(Info{Name: "test name"}) -} +//func (s InfoForDefaultValueFunc) Default() reflect.Value { +// return reflect.ValueOf(InfoForDefaultValueFunc{Name: "test name"}) +//} -//for test not same struct -type Info2 struct { - Ext string `d:"aaa"` - Name string `d:"123"` +type InfoForDefaultValueFunc struct { + Ext string `default:"aaa"` + Name string `default:"123"` } type Info struct { - Ext string `d:"aaa"` - Name string `d:"123"` + Ext string `default:"aaa"` + Name string `default:"123"` + BoolFalse bool `default:"false"` + BoolTrue bool `default:"true"` + Float float32 `default:"12.21"` + Float64 float64 `default:"12.51"` + Int int `default:"12*11"` + Int64 int64 `default:"12*11"` + NumberUint uint `default:"12"` +} + +func (s AnyInfo) Default() reflect.Value { + return reflect.ValueOf(AnyInfo{AnyInfoName: "test anyInfo name"}) +} + +type AnyInfo struct { + AnyInfoName string `default:"anyInfo"` } type ShowInfo struct { - Name string `d:"name"` + Name string `default:"name"` Info - CreateTime time.Time `d:"2020-01-02 03:04:01"` + *AnyInfo + AnyInfo2 AnyInfo + InfoForDefaultValueFunc InfoForDefaultValueFunc + CreateTime time.Time `default:"2020-01-02 03:04:01"` } func TestBindDefaultValue(t *testing.T) { var s ShowInfo BindDefaultValue(&s) - log.Printf("%+v", s) + data, _ := json.Marshal(s) + log.Printf("%s", data) } func BenchmarkBindDefaultValue(b *testing.B) { - var s ShowInfo for i := 0; i < b.N; i++ { + var s ShowInfo BindDefaultValue(&s) } } From 623f1c759232b3a0a476824e78dbc75bf4d4dda8 Mon Sep 17 00:00:00 2001 From: frank <8756012@qq.com> Date: Sun, 31 Jan 2021 02:10:40 +0800 Subject: [PATCH 3/7] fix anonymous field nil --- values_default.go | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/values_default.go b/values_default.go index bc9bc3f..7c474b2 100644 --- a/values_default.go +++ b/values_default.go @@ -64,6 +64,35 @@ func getFuncByType(k reflect.Type) DefaultValueFunc { defer mux.RUnlock() return regTypeFuncMap[k] } + +func getDefaultValueAndCheckEmbedded(v reflect.Value) (tv reflect.Value, ok bool) { + if !implDefaultInitValue(v.Type()) { + return + } + t := v.Type() + structV := v + if t.Kind() == reflect.Ptr { + t = v.Elem().Type() + structV = v.Elem() + } + for i := 0; i < t.NumField(); i++ { + f := t.Field(i) + if f.Anonymous { + if implDefaultInitValue(f.Type) { + if structV.Field(i).Kind() == reflect.Ptr && structV.Field(i).IsNil() { + return + } else { + break + } + } + } + } + dv, _ := v.Interface().(DefaultInitValue) + tv = dv.Default() + ok = true + return +} + func bindValue(v reflect.Value, tag string) { if v == ZeroValue || v.IsZero() { return @@ -72,11 +101,10 @@ func bindValue(v reflect.Value, tag string) { if t.Kind() == reflect.Ptr { t = v.Elem().Type() } - - if implDefaultInitValue(t) { - dv, _ := v.Interface().(DefaultInitValue) - //TODO 此处无法判断 指针类型带来的接口实现 会造成 default 执行报错 - tv := dv.Default() + if tv, ok := getDefaultValueAndCheckEmbedded(v); ok { + //dv, _ := v.Interface().(DefaultInitValue) + ////TODO 此处无法判断 指针类型带来的接口实现 会造成 default 执行报错,暂时利用深层以上方式 检测内嵌field是否实现了接口。 + //tv := dv.Default() if v.Type().Kind() == reflect.Ptr { if tv.Type() == t { v.Elem().Set(tv) From ca725d7d6635bc2ecddeead5caac3aaca2a735d1 Mon Sep 17 00:00:00 2001 From: frank <8756012@qq.com> Date: Sun, 31 Jan 2021 03:21:39 +0800 Subject: [PATCH 4/7] fix anonymous field nil --- values_default.go | 14 +++++--------- values_default_test.go | 18 +++++++++++++----- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/values_default.go b/values_default.go index 7c474b2..5f2ca1e 100644 --- a/values_default.go +++ b/values_default.go @@ -1,7 +1,6 @@ package mapper import ( - "log" "reflect" "sync" "time" @@ -66,7 +65,7 @@ func getFuncByType(k reflect.Type) DefaultValueFunc { } func getDefaultValueAndCheckEmbedded(v reflect.Value) (tv reflect.Value, ok bool) { - if !implDefaultInitValue(v.Type()) { + if !implDefaultInitValue(v.Type()) || (v.Type().Kind() == reflect.Ptr && v.IsZero()) { return } t := v.Type() @@ -94,17 +93,15 @@ func getDefaultValueAndCheckEmbedded(v reflect.Value) (tv reflect.Value, ok bool } func bindValue(v reflect.Value, tag string) { - if v == ZeroValue || v.IsZero() { - return - } t := v.Type() - if t.Kind() == reflect.Ptr { + if t.Kind() == reflect.Ptr && !v.IsZero() { t = v.Elem().Type() } if tv, ok := getDefaultValueAndCheckEmbedded(v); ok { //dv, _ := v.Interface().(DefaultInitValue) ////TODO 此处无法判断 指针类型带来的接口实现 会造成 default 执行报错,暂时利用深层以上方式 检测内嵌field是否实现了接口。 //tv := dv.Default() + if v.Type().Kind() == reflect.Ptr { if tv.Type() == t { v.Elem().Set(tv) @@ -119,7 +116,6 @@ func bindValue(v reflect.Value, tag string) { v.Set(tv) return } else { - log.Println(tv.Type()) } } @@ -127,11 +123,11 @@ func bindValue(v reflect.Value, tag string) { if t.Kind() == reflect.Struct { for i := 0; i < t.NumField(); i++ { if v.Type().Kind() == reflect.Ptr { - if v.Elem().Field(i).Kind() != reflect.Ptr && canDefaultBind(v.Elem().Type().Field(i), tag) && !checkSampleValue(v.Elem().Field(i), v.Elem().Type().Field(i), tag) { + if canDefaultBind(v.Elem().Type().Field(i), tag) && !checkSampleValue(v.Elem().Field(i), v.Elem().Type().Field(i), tag) { bindValue(v.Elem().Field(i), tag) } } else { - if v.Field(i).Kind() != reflect.Ptr && canDefaultBind(v.Type().Field(i), tag) && !checkSampleValue(v.Field(i), v.Type().Field(i), tag) { + if canDefaultBind(v.Type().Field(i), tag) && !checkSampleValue(v.Field(i), v.Type().Field(i), tag) { bindValue(v.Field(i), tag) } } diff --git a/values_default_test.go b/values_default_test.go index 3a77b12..391b733 100644 --- a/values_default_test.go +++ b/values_default_test.go @@ -22,8 +22,8 @@ type InfoForDefaultValueFunc struct { Name string `default:"123"` } type Info struct { - Ext string `default:"aaa"` Name string `default:"123"` + Ext string `default:"aaa"` BoolFalse bool `default:"false"` BoolTrue bool `default:"true"` Float float32 `default:"12.21"` @@ -34,14 +34,14 @@ type Info struct { } func (s AnyInfo) Default() reflect.Value { - return reflect.ValueOf(AnyInfo{AnyInfoName: "test anyInfo name"}) + return reflect.ValueOf(AnyInfo{AnyInfoName: "test anyInfo name~~~~"}) } type AnyInfo struct { - AnyInfoName string `default:"anyInfo"` + AnyInfoName string `default:"dddddanyInfo"` } type ShowInfo struct { - Name string `default:"name"` + //Name string `default:"name"` Info *AnyInfo AnyInfo2 AnyInfo @@ -50,10 +50,11 @@ type ShowInfo struct { } func TestBindDefaultValue(t *testing.T) { + t0 := time.Now() var s ShowInfo BindDefaultValue(&s) data, _ := json.Marshal(s) - log.Printf("%s", data) + log.Printf("%s %v", data, time.Now().Sub(t0)) } func BenchmarkBindDefaultValue(b *testing.B) { @@ -62,3 +63,10 @@ func BenchmarkBindDefaultValue(b *testing.B) { BindDefaultValue(&s) } } +func BenchmarkBindDefaultValue2(b *testing.B) { + data := []byte(`{"Name":"123","Ext":"aaa","BoolFalse":false,"BoolTrue":true,"Float":12.21,"Float64":12.51,"Int":132,"Int64":132,"NumberUint":12,"AnyInfo2":{"AnyInfoName":"test anyInfo name~~~~"},"InfoForDefaultValueFunc":{"Ext":"aaa","Name":"123"},"CreateTime":"2020-01-02T03:04:01+08:00"}`) + for i := 0; i < b.N; i++ { + var s ShowInfo + _ = json.Unmarshal(data, &s) + } +} From 3238290a3f87c0d88d9103d26632a64a136329b0 Mon Sep 17 00:00:00 2001 From: frank <8756012@qq.com> Date: Wed, 3 Feb 2021 14:58:12 +0800 Subject: [PATCH 5/7] remove reflect.Value.IsZero --- values_default.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/values_default.go b/values_default.go index 5f2ca1e..8de13c0 100644 --- a/values_default.go +++ b/values_default.go @@ -65,7 +65,7 @@ func getFuncByType(k reflect.Type) DefaultValueFunc { } func getDefaultValueAndCheckEmbedded(v reflect.Value) (tv reflect.Value, ok bool) { - if !implDefaultInitValue(v.Type()) || (v.Type().Kind() == reflect.Ptr && v.IsZero()) { + if !implDefaultInitValue(v.Type()) || (v.Type().Kind() == reflect.Ptr && v.Elem() == ZeroValue) { return } t := v.Type() @@ -94,7 +94,7 @@ func getDefaultValueAndCheckEmbedded(v reflect.Value) (tv reflect.Value, ok bool func bindValue(v reflect.Value, tag string) { t := v.Type() - if t.Kind() == reflect.Ptr && !v.IsZero() { + if t.Kind() == reflect.Ptr && v.Elem() != ZeroValue { t = v.Elem().Type() } if tv, ok := getDefaultValueAndCheckEmbedded(v); ok { From 745de3e5d5ec794b7a790dd529dc57928e52df7d Mon Sep 17 00:00:00 2001 From: frank <8756012@qq.com> Date: Wed, 3 Feb 2021 15:16:23 +0800 Subject: [PATCH 6/7] fix string bug --- values_default.go | 2 +- values_default_test.go | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/values_default.go b/values_default.go index 8de13c0..f59ad0d 100644 --- a/values_default.go +++ b/values_default.go @@ -160,7 +160,7 @@ func checkSampleValue(v reflect.Value, field reflect.StructField, tag string) (o } else { switch v.Kind() { case reflect.String: - v.Set(strFunc(tagValue)) + v.SetString(strFunc(tagValue).String()) ok = true case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: v.SetInt(int64Func(tagValue).Int()) diff --git a/values_default_test.go b/values_default_test.go index 391b733..376509a 100644 --- a/values_default_test.go +++ b/values_default_test.go @@ -20,6 +20,8 @@ func init() { type InfoForDefaultValueFunc struct { Ext string `default:"aaa"` Name string `default:"123"` + AA string `default:"aaaaaa"` + Int int `default:"12*11"` } type Info struct { Name string `default:"123"` @@ -40,11 +42,18 @@ func (s AnyInfo) Default() reflect.Value { type AnyInfo struct { AnyInfoName string `default:"dddddanyInfo"` } +type ReStr string +type ReInt int +type ReInfo Info +type ReBool bool type ShowInfo struct { - //Name string `default:"name"` Info *AnyInfo + ReInfo ReInfo AnyInfo2 AnyInfo + ReInt ReInt `default:"10"` + ReStr ReStr `default:"reStr"` + ReBool ReBool `default:"true"` InfoForDefaultValueFunc InfoForDefaultValueFunc CreateTime time.Time `default:"2020-01-02 03:04:01"` } @@ -54,12 +63,13 @@ func TestBindDefaultValue(t *testing.T) { var s ShowInfo BindDefaultValue(&s) data, _ := json.Marshal(s) + log.Printf("%+v", s) log.Printf("%s %v", data, time.Now().Sub(t0)) } func BenchmarkBindDefaultValue(b *testing.B) { + var s InfoForDefaultValueFunc for i := 0; i < b.N; i++ { - var s ShowInfo BindDefaultValue(&s) } } From 36ed4166f14ebbeb027b55073686d411c777bd07 Mon Sep 17 00:00:00 2001 From: frank <8756012@qq.com> Date: Thu, 4 Feb 2021 15:34:47 +0800 Subject: [PATCH 7/7] fix int64 continuous multiplication --- value_types.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/value_types.go b/value_types.go index 8ed6c84..5bcff02 100644 --- a/value_types.go +++ b/value_types.go @@ -13,16 +13,15 @@ func strFunc(str string) reflect.Value { //Support computing func int64Func(str string) reflect.Value { - //exp, err := parser.ParseExpr(str) - //if err == nil { - // fset := token.NewFileSet() - // _ = ast.Print(fset, exp) - //} + str = strings.TrimSpace(str) if strings.Contains(str, "*") { ss := strings.Split(str, "*") - a, _ := strconv.ParseInt(strings.TrimSpace(ss[0]), 10, 64) - b, _ := strconv.ParseInt(strings.TrimSpace(ss[1]), 10, 64) - return reflect.ValueOf(a * b) + var r int64 + r = 1 + for _, s := range ss { + r = r * int64Func(s).Int() + } + return reflect.ValueOf(r) } else { r, _ := strconv.ParseInt(str, 10, 64) return reflect.ValueOf(r)