Skip to content

Commit 0e471ea

Browse files
authored
fix(util/gconv): #3764 fix bool converting issue (#3765)
1 parent 3d63ebf commit 0e471ea

11 files changed

+341
-90
lines changed

util/gconv/gconv.go

+33-12
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,6 @@ func String(any interface{}) string {
181181
}
182182
return value.String()
183183
default:
184-
// Empty checks.
185-
if value == nil {
186-
return ""
187-
}
188184
if f, ok := value.(localinterface.IString); ok {
189185
// If the variable implements the String() interface,
190186
// then use that interface to perform the conversion
@@ -201,21 +197,33 @@ func String(any interface{}) string {
201197
kind = rv.Kind()
202198
)
203199
switch kind {
204-
case reflect.Chan,
200+
case
201+
reflect.Chan,
205202
reflect.Map,
206203
reflect.Slice,
207204
reflect.Func,
208-
reflect.Ptr,
209205
reflect.Interface,
210206
reflect.UnsafePointer:
211207
if rv.IsNil() {
212208
return ""
213209
}
214210
case reflect.String:
215211
return rv.String()
216-
}
217-
if kind == reflect.Ptr {
212+
case reflect.Ptr:
213+
if rv.IsNil() {
214+
return ""
215+
}
218216
return String(rv.Elem().Interface())
217+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
218+
return strconv.FormatInt(rv.Int(), 10)
219+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
220+
return strconv.FormatUint(rv.Uint(), 10)
221+
case reflect.Uintptr:
222+
return strconv.FormatUint(rv.Uint(), 10)
223+
case reflect.Float32, reflect.Float64:
224+
return strconv.FormatFloat(rv.Float(), 'f', -1, 64)
225+
case reflect.Bool:
226+
return strconv.FormatBool(rv.Bool())
219227
}
220228
// Finally, we use json.Marshal to convert.
221229
if jsonContent, err := json.Marshal(value); err != nil {
@@ -252,10 +260,23 @@ func Bool(any interface{}) bool {
252260
rv := reflect.ValueOf(any)
253261
switch rv.Kind() {
254262
case reflect.Ptr:
255-
return !rv.IsNil()
256-
case reflect.Map:
257-
fallthrough
258-
case reflect.Array:
263+
if rv.IsNil() {
264+
return false
265+
}
266+
if rv.Type().Elem().Kind() == reflect.Bool {
267+
return rv.Elem().Bool()
268+
}
269+
return Bool(rv.Elem().Interface())
270+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
271+
return rv.Int() != 0
272+
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
273+
return rv.Uint() != 0
274+
case reflect.Float32, reflect.Float64:
275+
return rv.Float() != 0
276+
case reflect.Bool:
277+
return rv.Bool()
278+
// TODO:(Map,Array,Slice,Struct) It might panic here for these types.
279+
case reflect.Map, reflect.Array:
259280
fallthrough
260281
case reflect.Slice:
261282
return rv.Len() != 0

util/gconv/gconv_float.go

+68-8
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
package gconv
88

99
import (
10+
"reflect"
1011
"strconv"
1112

1213
"github.com/gogf/gf/v2/encoding/gbinary"
@@ -24,13 +25,40 @@ func Float32(any interface{}) float32 {
2425
case float64:
2526
return float32(value)
2627
case []byte:
28+
// TODO: It might panic here for these types.
2729
return gbinary.DecodeToFloat32(value)
2830
default:
29-
if f, ok := value.(localinterface.IFloat32); ok {
30-
return f.Float32()
31+
rv := reflect.ValueOf(any)
32+
switch rv.Kind() {
33+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
34+
return float32(rv.Int())
35+
case reflect.Uintptr, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
36+
return float32(rv.Uint())
37+
case reflect.Float32, reflect.Float64:
38+
return float32(rv.Float())
39+
case reflect.Bool:
40+
if rv.Bool() {
41+
return 1
42+
}
43+
return 0
44+
case reflect.String:
45+
f, _ := strconv.ParseFloat(rv.String(), 32)
46+
return float32(f)
47+
case reflect.Ptr:
48+
if rv.IsNil() {
49+
return 0
50+
}
51+
if f, ok := value.(localinterface.IFloat32); ok {
52+
return f.Float32()
53+
}
54+
return Float32(rv.Elem().Interface())
55+
default:
56+
if f, ok := value.(localinterface.IFloat32); ok {
57+
return f.Float32()
58+
}
59+
v, _ := strconv.ParseFloat(String(any), 32)
60+
return float32(v)
3161
}
32-
v, _ := strconv.ParseFloat(String(any), 64)
33-
return float32(v)
3462
}
3563
}
3664

@@ -45,12 +73,44 @@ func Float64(any interface{}) float64 {
4573
case float64:
4674
return value
4775
case []byte:
76+
// TODO: It might panic here for these types.
4877
return gbinary.DecodeToFloat64(value)
4978
default:
50-
if f, ok := value.(localinterface.IFloat64); ok {
51-
return f.Float64()
79+
rv := reflect.ValueOf(any)
80+
switch rv.Kind() {
81+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
82+
return float64(rv.Int())
83+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
84+
return float64(rv.Uint())
85+
case reflect.Uintptr:
86+
return float64(rv.Uint())
87+
case reflect.Float32, reflect.Float64:
88+
// Please Note:
89+
// When the type is float32 or a custom type defined based on float32,
90+
// switching to float64 may result in a few extra decimal places.
91+
return rv.Float()
92+
case reflect.Bool:
93+
if rv.Bool() {
94+
return 1
95+
}
96+
return 0
97+
case reflect.String:
98+
f, _ := strconv.ParseFloat(rv.String(), 64)
99+
return f
100+
case reflect.Ptr:
101+
if rv.IsNil() {
102+
return 0
103+
}
104+
if f, ok := value.(localinterface.IFloat64); ok {
105+
return f.Float64()
106+
}
107+
return Float64(rv.Elem().Interface())
108+
default:
109+
if f, ok := value.(localinterface.IFloat64); ok {
110+
return f.Float64()
111+
}
112+
v, _ := strconv.ParseFloat(String(any), 64)
113+
return v
52114
}
53-
v, _ := strconv.ParseFloat(String(any), 64)
54-
return v
55115
}
56116
}

util/gconv/gconv_int.go

+35-36
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package gconv
88

99
import (
1010
"math"
11+
"reflect"
1112
"strconv"
1213

1314
"github.com/gogf/gf/v2/encoding/gbinary"
@@ -63,44 +64,37 @@ func Int64(any interface{}) int64 {
6364
if any == nil {
6465
return 0
6566
}
66-
switch value := any.(type) {
67-
case int:
68-
return int64(value)
69-
case int8:
70-
return int64(value)
71-
case int16:
72-
return int64(value)
73-
case int32:
74-
return int64(value)
75-
case int64:
76-
return value
77-
case uint:
78-
return int64(value)
79-
case uint8:
80-
return int64(value)
81-
case uint16:
82-
return int64(value)
83-
case uint32:
84-
return int64(value)
85-
case uint64:
86-
return int64(value)
87-
case float32:
88-
return int64(value)
89-
case float64:
90-
return int64(value)
91-
case bool:
92-
if value {
67+
rv := reflect.ValueOf(any)
68+
switch rv.Kind() {
69+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
70+
return int64(rv.Int())
71+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
72+
return int64(rv.Uint())
73+
case reflect.Uintptr:
74+
return int64(rv.Uint())
75+
case reflect.Float32, reflect.Float64:
76+
return int64(rv.Float())
77+
case reflect.Bool:
78+
if rv.Bool() {
9379
return 1
9480
}
9581
return 0
96-
case []byte:
97-
return gbinary.DecodeToInt64(value)
98-
default:
99-
if f, ok := value.(localinterface.IInt64); ok {
82+
case reflect.Ptr:
83+
if rv.IsNil() {
84+
return 0
85+
}
86+
if f, ok := any.(localinterface.IInt64); ok {
10087
return f.Int64()
10188
}
89+
return Int64(rv.Elem().Interface())
90+
case reflect.Slice:
91+
// TODO: It might panic here for these types.
92+
if rv.Type().Elem().Kind() == reflect.Uint8 {
93+
return gbinary.DecodeToInt64(rv.Bytes())
94+
}
95+
case reflect.String:
10296
var (
103-
s = String(value)
97+
s = rv.String()
10498
isMinus = false
10599
)
106100
if len(s) > 0 {
@@ -111,7 +105,7 @@ func Int64(any interface{}) int64 {
111105
s = s[1:]
112106
}
113107
}
114-
// Hexadecimal
108+
// Hexadecimal.
115109
if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
116110
if v, e := strconv.ParseInt(s[2:], 16, 64); e == nil {
117111
if isMinus {
@@ -120,18 +114,23 @@ func Int64(any interface{}) int64 {
120114
return v
121115
}
122116
}
123-
// Decimal
117+
// Decimal.
124118
if v, e := strconv.ParseInt(s, 10, 64); e == nil {
125119
if isMinus {
126120
return -v
127121
}
128122
return v
129123
}
130-
// Float64
131-
if valueInt64 := Float64(value); math.IsNaN(valueInt64) {
124+
// Float64.
125+
if valueInt64 := Float64(s); math.IsNaN(valueInt64) {
132126
return 0
133127
} else {
134128
return int64(valueInt64)
135129
}
130+
default:
131+
if f, ok := any.(localinterface.IInt64); ok {
132+
return f.Int64()
133+
}
136134
}
135+
return 0
137136
}

util/gconv/gconv_uint.go

+34-33
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package gconv
88

99
import (
1010
"math"
11+
"reflect"
1112
"strconv"
1213

1314
"github.com/gogf/gf/v2/encoding/gbinary"
@@ -63,43 +64,38 @@ func Uint64(any interface{}) uint64 {
6364
if any == nil {
6465
return 0
6566
}
66-
switch value := any.(type) {
67-
case int:
68-
return uint64(value)
69-
case int8:
70-
return uint64(value)
71-
case int16:
72-
return uint64(value)
73-
case int32:
74-
return uint64(value)
75-
case int64:
76-
return uint64(value)
77-
case uint:
78-
return uint64(value)
79-
case uint8:
80-
return uint64(value)
81-
case uint16:
82-
return uint64(value)
83-
case uint32:
84-
return uint64(value)
85-
case uint64:
86-
return value
87-
case float32:
88-
return uint64(value)
89-
case float64:
90-
return uint64(value)
91-
case bool:
92-
if value {
67+
rv := reflect.ValueOf(any)
68+
switch rv.Kind() {
69+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
70+
return uint64(rv.Int())
71+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
72+
return uint64(rv.Uint())
73+
case reflect.Uintptr:
74+
return uint64(rv.Uint())
75+
case reflect.Float32, reflect.Float64:
76+
return uint64(rv.Float())
77+
case reflect.Bool:
78+
if rv.Bool() {
9379
return 1
9480
}
9581
return 0
96-
case []byte:
97-
return gbinary.DecodeToUint64(value)
98-
default:
99-
if f, ok := value.(localinterface.IUint64); ok {
82+
case reflect.Ptr:
83+
if rv.IsNil() {
84+
return 0
85+
}
86+
if f, ok := any.(localinterface.IUint64); ok {
10087
return f.Uint64()
10188
}
102-
s := String(value)
89+
return Uint64(rv.Elem().Interface())
90+
case reflect.Slice:
91+
// TODO:These types should be panic
92+
if rv.Type().Elem().Kind() == reflect.Uint8 {
93+
return gbinary.DecodeToUint64(rv.Bytes())
94+
}
95+
case reflect.String:
96+
var (
97+
s = rv.String()
98+
)
10399
// Hexadecimal
104100
if len(s) > 2 && s[0] == '0' && (s[1] == 'x' || s[1] == 'X') {
105101
if v, e := strconv.ParseUint(s[2:], 16, 64); e == nil {
@@ -111,10 +107,15 @@ func Uint64(any interface{}) uint64 {
111107
return v
112108
}
113109
// Float64
114-
if valueFloat64 := Float64(value); math.IsNaN(valueFloat64) {
110+
if valueFloat64 := Float64(any); math.IsNaN(valueFloat64) {
115111
return 0
116112
} else {
117113
return uint64(valueFloat64)
118114
}
115+
default:
116+
if f, ok := any.(localinterface.IUint64); ok {
117+
return f.Uint64()
118+
}
119119
}
120+
return 0
120121
}

0 commit comments

Comments
 (0)