mirror of
https://github.com/jefferyjob/go-easy-utils.git
synced 2025-10-06 23:42:45 +08:00
unit test jsonToStruct
This commit is contained in:
@@ -1,20 +1,29 @@
|
|||||||
# jsonUtil
|
# jsonUtil
|
||||||
|
|
||||||
根据结构体的字段类型和标签来自动选择将 JSON 值转换为相应的类型。
|
## Introduce
|
||||||
|
|
||||||
支持的字段类型包括 string、int、int8、int16、int32、int64、uint、uint8、uint16、uint32、uint64、bool、float32 和 float64。
|
<details>
|
||||||
|
<summary>English</summary>
|
||||||
|
<pre>
|
||||||
|
JsonToStruct is a method that parses a JSON string into a struct. This method accepts two parameters:
|
||||||
|
- jsonData: the JSON string to be parsed
|
||||||
|
- result: a pointer to an instance of a struct used to store the parsed data
|
||||||
|
The method uses reflection to parse the struct and extracts the corresponding values from the JSON based on the fields defined in the struct and their corresponding JSON tags. If a field in the struct is a nested struct, it recursively parses the nested struct and stores the result in the parent struct.
|
||||||
|
This method can handle basic data types such as strings, integers, floating-point numbers, booleans, as well as nested structs and slices. If a value in the JSON string cannot be converted to the target type, the method will return an error.
|
||||||
|
</pre>
|
||||||
|
</details>
|
||||||
|
|
||||||
支持的标签有 "json"、"jsonb" 和 "mapstructure"。
|
<details>
|
||||||
- "json" 和 "jsonb" 标签指示解析 JSON 时使用的键名。
|
<summary>简体中文</summary>
|
||||||
- "mapstructure" 标签指示字段名的映射关系。
|
<pre>
|
||||||
|
JsonToStruct 是一个将JSON字符串解析为结构体的方法。这个方法接受两个参数:
|
||||||
|
- jsonData:待解析的JSON字符串
|
||||||
|
- result:用于存储解析后数据的结构体实例的指针
|
||||||
|
该方法使用了反射机制来解析结构体,并根据结构体中定义的字段和对应的json标签从JSON中提取对应的值。如果结构体的字段是一个嵌套的结构体,它将递归解析嵌套的结构体,并将结果存储在父结构体中。
|
||||||
|
该方法可以处理基本数据类型,如字符串、整数、浮点数、布尔值以及嵌套的结构体和切片。如果JSON字符串中的值无法转换为目标类型,该方法将返回一个错误。
|
||||||
|
</pre>
|
||||||
|
</details>
|
||||||
|
|
||||||
如果 JSON 中的某些键在结构体中没有对应的字段,则它们将被忽略。
|
|
||||||
如果 JSON 中的某些键的类型与结构体中的字段类型不匹配,则会引发解析错误。
|
|
||||||
|
|
||||||
参数 jsonData 是要解析的 JSON 字符串。
|
|
||||||
参数 result 是指向要填充 JSON 值的结构体指针。
|
|
||||||
|
|
||||||
如果解析成功,则返回 nil。如果解析失败,则返回解析错误。
|
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
@@ -25,6 +34,70 @@ go get -u github.com/jefferyjob/go-easy-utils/jsonUtil
|
|||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
```go
|
```go
|
||||||
// JsonToStruct 将 JSON 字符串解析为指定的结构体指针
|
// JsonToStruct Parses JSON into a specified structure pointer
|
||||||
|
// 将JSON解析为指定的结构体指针
|
||||||
func JsonToStruct(jsonData string, result interface{}) error
|
func JsonToStruct(jsonData string, result interface{}) error
|
||||||
|
```
|
||||||
|
|
||||||
|
## Demo
|
||||||
|
|
||||||
|
```go
|
||||||
|
// name uses two json tags
|
||||||
|
// age is defined as int, and the value of json is string
|
||||||
|
// is_use is defined as bool, the value of json is int
|
||||||
|
func TestDemo1(t *testing.T) {
|
||||||
|
jsonData := `{
|
||||||
|
"name": "make",
|
||||||
|
"age": "22",
|
||||||
|
"is_use": "1"
|
||||||
|
}`
|
||||||
|
type People struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
IsUse bool `json:"is_use"`
|
||||||
|
}
|
||||||
|
var people People
|
||||||
|
if err := JsonToStruct(jsonData, &people); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("%+v \n", people)
|
||||||
|
// return
|
||||||
|
// {Name:make Age:22 IsUse:true}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```go
|
||||||
|
// Structure nesting and slice nesting processing
|
||||||
|
func TestJsonToStructDemo2(t *testing.T) {
|
||||||
|
type Address struct {
|
||||||
|
City string `json:"city"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
}
|
||||||
|
type Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
Address Address `json:"address"`
|
||||||
|
Interests []string `json:"interests"`
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData2 := `{
|
||||||
|
"name": "Bob",
|
||||||
|
"age": "25",
|
||||||
|
"address": {
|
||||||
|
"city": "Shanghai",
|
||||||
|
"country": "China"
|
||||||
|
},
|
||||||
|
"interests": ["reading", "swimming"]
|
||||||
|
}`
|
||||||
|
|
||||||
|
var person Person
|
||||||
|
err := JsonToStruct(jsonData2, &person)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("%+v \n", person)
|
||||||
|
// {Name:Bob Age:25 Address:{City:Shanghai Country:China} Interests:[reading swimming]}
|
||||||
|
}
|
||||||
```
|
```
|
@@ -2,13 +2,13 @@ package jsonUtil
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/jefferyjob/go-easy-utils"
|
"log"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// JsonToStruct 将 JSON 字符串解析为指定的结构体指针
|
// JsonToStruct Parses JSON into a specified structure pointer
|
||||||
|
// 将JSON解析为指定的结构体指针
|
||||||
func JsonToStruct(jsonData string, result interface{}) error {
|
func JsonToStruct(jsonData string, result interface{}) error {
|
||||||
var data map[string]interface{}
|
var data map[string]interface{}
|
||||||
err := json.Unmarshal([]byte(jsonData), &data)
|
err := json.Unmarshal([]byte(jsonData), &data)
|
||||||
@@ -41,27 +41,30 @@ func JsonToStruct(jsonData string, result interface{}) error {
|
|||||||
|
|
||||||
switch fieldValue.Kind() {
|
switch fieldValue.Kind() {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
fieldValue.SetString(toString(value))
|
fieldValue.SetString(toStringReflect(value))
|
||||||
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
val, err := toInt64(value)
|
val, err := toInt64Reflect(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("toInt64Reflect err:%s \n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fieldValue.SetInt(val)
|
fieldValue.SetInt(val)
|
||||||
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
val, err := toUint64(value)
|
val, err := toUint64Reflect(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("toUint64Reflect err:%s \n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fieldValue.SetUint(val)
|
fieldValue.SetUint(val)
|
||||||
case reflect.Float32, reflect.Float64:
|
case reflect.Float32, reflect.Float64:
|
||||||
val, err := toFloat64(value)
|
val, err := toFloat64Reflect(value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("toFloat64Reflect err:%s \n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fieldValue.SetFloat(val)
|
fieldValue.SetFloat(val)
|
||||||
case reflect.Bool:
|
case reflect.Bool:
|
||||||
val := toBool(value)
|
val := toBoolReflect(value)
|
||||||
fieldValue.SetBool(val)
|
fieldValue.SetBool(val)
|
||||||
case reflect.Struct:
|
case reflect.Struct:
|
||||||
if subData, ok := value.(map[string]interface{}); ok {
|
if subData, ok := value.(map[string]interface{}); ok {
|
||||||
@@ -98,196 +101,15 @@ func JsonToStruct(jsonData string, result interface{}) error {
|
|||||||
// fieldValue.Set(reflect.ValueOf(value))
|
// fieldValue.Set(reflect.ValueOf(value))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//func isJSON(jsonStr string) bool {
|
||||||
|
// var raw json.RawMessage
|
||||||
|
// return json.Unmarshal([]byte(jsonStr), &raw) == nil
|
||||||
|
//}
|
||||||
|
|
||||||
func convertToJSONString(data map[string]interface{}) string {
|
func convertToJSONString(data map[string]interface{}) string {
|
||||||
jsonBytes, _ := json.Marshal(data)
|
jsonBytes, _ := json.Marshal(data)
|
||||||
return string(jsonBytes)
|
return string(jsonBytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toBool(value interface{}) bool {
|
|
||||||
switch v := value.(type) {
|
|
||||||
case bool:
|
|
||||||
return v
|
|
||||||
case string:
|
|
||||||
return v != "" && v != "false" && v != "0"
|
|
||||||
case int, int8, int16, int32, int64:
|
|
||||||
return v != 0
|
|
||||||
case uint, uint8, uint16, uint32, uint64, uintptr:
|
|
||||||
return v != 0
|
|
||||||
case float32, float64:
|
|
||||||
return v != 0.0
|
|
||||||
case complex64, complex128:
|
|
||||||
return v != 0+0i
|
|
||||||
case nil:
|
|
||||||
return false
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toString(value interface{}) string {
|
|
||||||
if value == nil {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
switch v := value.(type) {
|
|
||||||
case string:
|
|
||||||
return v
|
|
||||||
case int:
|
|
||||||
return strconv.Itoa(v)
|
|
||||||
case int8:
|
|
||||||
return strconv.FormatInt(int64(v), 10)
|
|
||||||
case int16:
|
|
||||||
return strconv.FormatInt(int64(v), 10)
|
|
||||||
case int32:
|
|
||||||
return strconv.FormatInt(int64(v), 10)
|
|
||||||
case int64:
|
|
||||||
return strconv.FormatInt(v, 10)
|
|
||||||
case uint:
|
|
||||||
return strconv.FormatUint(uint64(v), 10)
|
|
||||||
case uint8:
|
|
||||||
return strconv.FormatUint(uint64(v), 10)
|
|
||||||
case uint16:
|
|
||||||
return strconv.FormatUint(uint64(v), 10)
|
|
||||||
case uint32:
|
|
||||||
return strconv.FormatUint(uint64(v), 10)
|
|
||||||
case uint64:
|
|
||||||
return strconv.FormatUint(v, 10)
|
|
||||||
case float32:
|
|
||||||
return strconv.FormatFloat(float64(v), 'f', -1, 32)
|
|
||||||
case float64:
|
|
||||||
return strconv.FormatFloat(v, 'f', -1, 64)
|
|
||||||
case bool:
|
|
||||||
return strconv.FormatBool(v)
|
|
||||||
default:
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toInt64(value interface{}) (int64, error) {
|
|
||||||
if value == nil {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch value.(type) {
|
|
||||||
case float32:
|
|
||||||
return int64(value.(float32)), nil
|
|
||||||
case float64:
|
|
||||||
return int64(value.(float64)), nil
|
|
||||||
case string:
|
|
||||||
intValue, err := strconv.ParseInt(value.(string), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, go_easy_utils.ErrSyntax
|
|
||||||
}
|
|
||||||
return intValue, nil
|
|
||||||
case int:
|
|
||||||
return int64(value.(int)), nil
|
|
||||||
case int8:
|
|
||||||
return int64(value.(int8)), nil
|
|
||||||
case int16:
|
|
||||||
return int64(value.(int16)), nil
|
|
||||||
case int32:
|
|
||||||
return int64(value.(int32)), nil
|
|
||||||
case int64:
|
|
||||||
return value.(int64), nil
|
|
||||||
case interface{}:
|
|
||||||
return 0, nil
|
|
||||||
default:
|
|
||||||
return 0, go_easy_utils.ErrType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toUint64(value interface{}) (uint64, error) {
|
|
||||||
if value == nil {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch value.(type) {
|
|
||||||
case float32:
|
|
||||||
v := value.(float32)
|
|
||||||
if v < 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return uint64(v), nil
|
|
||||||
case float64:
|
|
||||||
v := value.(float64)
|
|
||||||
if v < 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return uint64(v), nil
|
|
||||||
case string:
|
|
||||||
intValue, err := strconv.ParseUint(value.(string), 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, go_easy_utils.ErrSyntax
|
|
||||||
}
|
|
||||||
return intValue, nil
|
|
||||||
case uint:
|
|
||||||
return uint64(value.(uint)), nil
|
|
||||||
case uint8:
|
|
||||||
return uint64(value.(uint8)), nil
|
|
||||||
case uint16:
|
|
||||||
return uint64(value.(uint16)), nil
|
|
||||||
case uint32:
|
|
||||||
return uint64(value.(uint32)), nil
|
|
||||||
case uint64:
|
|
||||||
return value.(uint64), nil
|
|
||||||
case int:
|
|
||||||
v := value.(int)
|
|
||||||
if v < 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return uint64(v), nil
|
|
||||||
case int8:
|
|
||||||
v := value.(int8)
|
|
||||||
if v < 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return uint64(v), nil
|
|
||||||
case int16:
|
|
||||||
v := value.(int16)
|
|
||||||
if v < 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return uint64(v), nil
|
|
||||||
case int32:
|
|
||||||
v := value.(int32)
|
|
||||||
if v < 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return uint64(v), nil
|
|
||||||
case int64:
|
|
||||||
v := value.(int64)
|
|
||||||
if v < 0 {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
return uint64(v), nil
|
|
||||||
case interface{}:
|
|
||||||
return 0, nil
|
|
||||||
default:
|
|
||||||
return 0, go_easy_utils.ErrType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func toFloat64(value interface{}) (float64, error) {
|
|
||||||
if value == nil {
|
|
||||||
return 0, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch value.(type) {
|
|
||||||
case float32:
|
|
||||||
return float64(value.(float32)), nil
|
|
||||||
case float64:
|
|
||||||
return value.(float64), nil
|
|
||||||
case string:
|
|
||||||
floatValue, err := strconv.ParseFloat(value.(string), 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, go_easy_utils.ErrSyntax
|
|
||||||
}
|
|
||||||
return floatValue, nil
|
|
||||||
default:
|
|
||||||
return 0, go_easy_utils.ErrType
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -6,6 +6,77 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// name uses two json tags
|
||||||
|
// age is defined as int, and the value of json is string
|
||||||
|
// is_use is defined as bool, the value of json is int
|
||||||
|
func TestDemo1(t *testing.T) {
|
||||||
|
jsonData := `{
|
||||||
|
"name": "make",
|
||||||
|
"age": "22",
|
||||||
|
"is_use": "1"
|
||||||
|
}`
|
||||||
|
type People struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
IsUse bool `json:"is_use"`
|
||||||
|
}
|
||||||
|
var people People
|
||||||
|
if err := JsonToStruct(jsonData, &people); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("%+v \n", people)
|
||||||
|
// return
|
||||||
|
// {Name:make Age:22 IsUse:true}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Structure nesting and slice nesting processing
|
||||||
|
func TestJsonToStructDemo2(t *testing.T) {
|
||||||
|
type Address struct {
|
||||||
|
City string `json:"city"`
|
||||||
|
Country string `json:"country"`
|
||||||
|
}
|
||||||
|
type Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Age int `json:"age"`
|
||||||
|
Address Address `json:"address"`
|
||||||
|
Interests []string `json:"interests"`
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData2 := `{
|
||||||
|
"name": "Bob",
|
||||||
|
"age": "25",
|
||||||
|
"address": {
|
||||||
|
"city": "Shanghai",
|
||||||
|
"country": "China"
|
||||||
|
},
|
||||||
|
"interests": ["reading", "swimming"]
|
||||||
|
}`
|
||||||
|
|
||||||
|
var person Person
|
||||||
|
err := JsonToStruct(jsonData2, &person)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Printf("%+v \n", person)
|
||||||
|
// {Name:Bob Age:25 Address:{City:Shanghai Country:China} Interests:[reading swimming]}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 非法的json字符串
|
||||||
|
func TestJsonToStructErrJson(t *testing.T) {
|
||||||
|
jsonData := `{"name":}`
|
||||||
|
type People struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
var people People
|
||||||
|
err := JsonToStruct(jsonData, &people)
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("err %s", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestJsonToStruct1(t *testing.T) {
|
func TestJsonToStruct1(t *testing.T) {
|
||||||
type Address struct {
|
type Address struct {
|
||||||
City string `json:"city"`
|
City string `json:"city"`
|
||||||
@@ -108,38 +179,6 @@ func TestJsonToStruct2(t *testing.T) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestJsonToStruct3(t *testing.T) {
|
|
||||||
type Address struct {
|
|
||||||
City string `json:"city"`
|
|
||||||
Country string `json:"country"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type Person struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Age int `json:"age"`
|
|
||||||
Address Address `json:"address"`
|
|
||||||
Interests []string `json:"interests"`
|
|
||||||
}
|
|
||||||
|
|
||||||
jsonData2 := `{
|
|
||||||
"name": "Bob",
|
|
||||||
"age": "25",
|
|
||||||
"address": {
|
|
||||||
"city": "Shanghai",
|
|
||||||
"country": "China"
|
|
||||||
},
|
|
||||||
"interests": ["reading", "swimming"]
|
|
||||||
}`
|
|
||||||
|
|
||||||
var person2 Person
|
|
||||||
err := JsonToStruct(jsonData2, &person2)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("person2:%+v,, address:%+v \n", person2, person2.Address)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 多层级json测试
|
// 多层级json测试
|
||||||
func TestJsonToStruct4(t *testing.T) {
|
func TestJsonToStruct4(t *testing.T) {
|
||||||
type Address struct {
|
type Address struct {
|
||||||
@@ -242,7 +281,3 @@ func TestJsonToStruct7(t *testing.T) {
|
|||||||
|
|
||||||
fmt.Printf("%#v \n", student)
|
fmt.Printf("%#v \n", student)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToUint64(t *testing.T) {
|
|
||||||
fmt.Println(toUint64(""))
|
|
||||||
}
|
|
||||||
|
42
jsonUtil/log.md
Normal file
42
jsonUtil/log.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// 检查解引用后的值是否为 nil
|
||||||
|
|
||||||
|
```go
|
||||||
|
if reflect.ValueOf(i).Kind() == reflect.Ptr && reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
```go
|
||||||
|
v := reflect.ValueOf(i)
|
||||||
|
for v.Kind() == reflect.Ptr {
|
||||||
|
if v.IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
v = v.Elem()
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
这两个写法都是使用反射判断指针是否为nil,但它们的实现方式略有不同。
|
||||||
|
|
||||||
|
第一种写法将值i转换为反射值,并检查其种类是否为指针(reflect.Ptr),然后检查其是否为nil(reflect.Value.IsNil())。如果是,则返回0和nil。
|
||||||
|
|
||||||
|
第二种写法首先获取值i的反射值v,并检查其种类是否为指针。如果是,则继续获取其指向的元素(reflect.Value.Elem()),并将其赋给v,以便进一步检查。这个过程一直重复,直到v不再是指针或者v指向的元素不是nil为止。
|
||||||
|
|
||||||
|
两种写法都可以检查指针是否为nil,但第二种写法允许进一步检查指针指向的元素是否为nil,因此更加灵活和精确。
|
||||||
|
|
||||||
|
```go
|
||||||
|
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 如果是指针类型
|
||||||
|
//这段代码的作用是将value指向的值转换为非指针类型的值,具体来说,它会循环检查v是否为指针类型,如果是指针类型,则通过Elem方法获取其指向的值,直到v不再是指针类型为止。
|
||||||
|
//
|
||||||
|
//在reflect包中,指针类型和其指向的值的类型是不同的。例如,一个指向int类型的指针,其类型是*int,而其指向的值的类型是int。因此,在使用reflect包时,我们需要注意区分指针类型和其指向的值的类型,否则可能会出现类型错误等问题。
|
||||||
|
//
|
||||||
|
//因此,对于value为指针类型的情况,我们需要通过Elem方法获取其指向的值,然后再进行类型转换。而在使用Elem方法之前,我们需要先检查v是否为指针类型,因此使用循环语句进行判断。
|
113
jsonUtil/to_bool.go
Normal file
113
jsonUtil/to_bool.go
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toBool(i interface{}) bool {
|
||||||
|
if i == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
i = reflect.ValueOf(i).Elem().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := i.(type) {
|
||||||
|
case bool:
|
||||||
|
return v
|
||||||
|
case int:
|
||||||
|
return v != 0
|
||||||
|
case int8:
|
||||||
|
return v != 0
|
||||||
|
case int16:
|
||||||
|
return v != 0
|
||||||
|
case int32:
|
||||||
|
return v != 0
|
||||||
|
case int64:
|
||||||
|
return v != 0
|
||||||
|
case uint:
|
||||||
|
return v != 0
|
||||||
|
case uint8:
|
||||||
|
return v != 0
|
||||||
|
case uint16:
|
||||||
|
return v != 0
|
||||||
|
case uint32:
|
||||||
|
return v != 0
|
||||||
|
case uint64:
|
||||||
|
return v != 0
|
||||||
|
case uintptr:
|
||||||
|
return v != 0
|
||||||
|
case float32:
|
||||||
|
return v != 0
|
||||||
|
case float64:
|
||||||
|
return v != 0
|
||||||
|
case complex64:
|
||||||
|
return v != 0
|
||||||
|
case complex128:
|
||||||
|
return v != 0
|
||||||
|
case string:
|
||||||
|
if v == "true" {
|
||||||
|
return true
|
||||||
|
} else if v == "false" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return v != ""
|
||||||
|
case fmt.Stringer:
|
||||||
|
return v.String() != ""
|
||||||
|
case interface{ IsNil() bool }:
|
||||||
|
return !v.IsNil()
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toBoolReflect(i interface{}) bool {
|
||||||
|
if i == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查解引用后的值是否为 nil
|
||||||
|
if reflect.ValueOf(i).Kind() == reflect.Ptr && reflect.ValueOf(i).IsNil() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
v := reflect.ValueOf(i)
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
v = reflect.ValueOf(i).Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Bool:
|
||||||
|
return v.Bool()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return v.Int() != 0
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return v.Uint() != 0
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return v.Float() != 0
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
return v.Complex() != 0
|
||||||
|
case reflect.String:
|
||||||
|
val := v.String()
|
||||||
|
if val == "true" {
|
||||||
|
return true
|
||||||
|
} else if val == "false" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return v.String() != ""
|
||||||
|
//case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Slice:
|
||||||
|
// return !v.IsNil()
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
57
jsonUtil/to_bool_test.go
Normal file
57
jsonUtil/to_bool_test.go
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestToBool(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
input interface{}
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{true, true},
|
||||||
|
{false, false},
|
||||||
|
{int(-1), true},
|
||||||
|
{int(1), true},
|
||||||
|
{int(0), false},
|
||||||
|
{int8(1), true},
|
||||||
|
{int8(0), false},
|
||||||
|
{int16(1), true},
|
||||||
|
{int16(0), false},
|
||||||
|
{int32(1), true},
|
||||||
|
{int32(0), false},
|
||||||
|
{int64(1), true},
|
||||||
|
{int64(0), false},
|
||||||
|
{uint(1), true},
|
||||||
|
{uint(0), false},
|
||||||
|
{uint8(1), true},
|
||||||
|
{uint8(0), false},
|
||||||
|
{uint16(1), true},
|
||||||
|
{uint16(0), false},
|
||||||
|
{uint32(1), true},
|
||||||
|
{uint32(0), false},
|
||||||
|
{uint64(1), true},
|
||||||
|
{uint64(0), false},
|
||||||
|
{float32(1.0), true},
|
||||||
|
{float32(0.0), false},
|
||||||
|
{float64(1.0), true},
|
||||||
|
{float64(0.0), false},
|
||||||
|
{"abc", true},
|
||||||
|
{"true", true},
|
||||||
|
{"false", false},
|
||||||
|
{"", false},
|
||||||
|
{nil, false},
|
||||||
|
{complex64(1 + 1i), true},
|
||||||
|
{complex64(0 + 0i), false},
|
||||||
|
{complex128(1 + 1i), true},
|
||||||
|
{complex128(0 + 0i), false},
|
||||||
|
{(*int)(nil), false},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
if got := toBool(test.input); got != test.want {
|
||||||
|
t.Errorf("toBool(%v) = %v; want %v", test.input, got, test.want)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got := toBoolReflect(test.input); got != test.want {
|
||||||
|
t.Errorf("toBool(%v) = %v; want %v", test.input, got, test.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
156
jsonUtil/to_float.go
Normal file
156
jsonUtil/to_float.go
Normal file
@@ -0,0 +1,156 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/jefferyjob/go-easy-utils"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toFloat64(i interface{}) (float64, error) {
|
||||||
|
if i == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
i = reflect.ValueOf(i).Elem().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := i.(type) {
|
||||||
|
case float32:
|
||||||
|
return float64(v), nil
|
||||||
|
case float64:
|
||||||
|
return v, nil
|
||||||
|
case string:
|
||||||
|
floatValue, err := strconv.ParseFloat(v, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, go_easy_utils.ErrSyntax
|
||||||
|
}
|
||||||
|
return floatValue, nil
|
||||||
|
case uint:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint8:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint16:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint32:
|
||||||
|
return float64(v), nil
|
||||||
|
case uint64:
|
||||||
|
return float64(v), nil
|
||||||
|
case int:
|
||||||
|
return float64(v), nil
|
||||||
|
case int8:
|
||||||
|
return float64(v), nil
|
||||||
|
case int16:
|
||||||
|
return float64(v), nil
|
||||||
|
case int32:
|
||||||
|
return float64(v), nil
|
||||||
|
case int64:
|
||||||
|
return float64(v), nil
|
||||||
|
case complex64:
|
||||||
|
return float64(real(v)), nil
|
||||||
|
case complex128:
|
||||||
|
return real(v), nil
|
||||||
|
case bool:
|
||||||
|
if v {
|
||||||
|
return 1, nil
|
||||||
|
} else {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
//case *float32:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *float64:
|
||||||
|
// return *v, nil
|
||||||
|
//case *string:
|
||||||
|
// floatValue, err := strconv.ParseFloat(*v, 64)
|
||||||
|
// if err != nil {
|
||||||
|
// return 0, go_easy_utils.ErrSyntax
|
||||||
|
// }
|
||||||
|
// return floatValue, nil
|
||||||
|
//case *uint:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *uint8:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *uint16:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *uint32:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *uint64:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *int:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *int8:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *int16:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *int32:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *int64:
|
||||||
|
// return float64(*v), nil
|
||||||
|
//case *complex64:
|
||||||
|
// return float64(real(*v)), nil
|
||||||
|
//case *complex128:
|
||||||
|
// return real(*v), nil
|
||||||
|
//case *bool:
|
||||||
|
// if v != nil && *v {
|
||||||
|
// return 1, nil
|
||||||
|
// } else {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
default:
|
||||||
|
return 0, go_easy_utils.ErrType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toFloat64Reflect(i interface{}) (float64, error) {
|
||||||
|
if i == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查解引用后的值是否为 nil
|
||||||
|
if reflect.ValueOf(i).Kind() == reflect.Ptr && reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v := reflect.ValueOf(i)
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
v = reflect.ValueOf(i).Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return v.Float(), nil
|
||||||
|
case reflect.String:
|
||||||
|
floatValue, err := strconv.ParseFloat(v.String(), 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, go_easy_utils.ErrSyntax
|
||||||
|
}
|
||||||
|
return floatValue, nil
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
fmt.Println("怎么可以到这里呢")
|
||||||
|
return float64(v.Int()), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
||||||
|
return float64(v.Uint()), nil
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
return real(v.Complex()), nil
|
||||||
|
case reflect.Bool:
|
||||||
|
if v.Bool() {
|
||||||
|
return 1, nil
|
||||||
|
} else {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
//case reflect.Ptr, reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Slice:
|
||||||
|
// return 0, nil
|
||||||
|
default:
|
||||||
|
return 0, go_easy_utils.ErrType
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
279
jsonUtil/to_float_test.go
Normal file
279
jsonUtil/to_float_test.go
Normal file
@@ -0,0 +1,279 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
go_easy_utils "github.com/jefferyjob/go-easy-utils"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
//func TestFloat(t *testing.T) {
|
||||||
|
// var data1 interface{}
|
||||||
|
// data1 = 123
|
||||||
|
// fmt.Println(toFloat64Reflect(data1))
|
||||||
|
//
|
||||||
|
// data2 := int16Ptr(80)
|
||||||
|
// fmt.Println(toFloat64Reflect(data2))
|
||||||
|
//
|
||||||
|
// data3 := map[interface{}]interface{}{
|
||||||
|
// "aaa": "aaa",
|
||||||
|
// }
|
||||||
|
// fmt.Println(toFloat64Reflect(data3))
|
||||||
|
//}
|
||||||
|
|
||||||
|
func TestToFloat64(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
value interface{}
|
||||||
|
expected float64
|
||||||
|
expectedErr error
|
||||||
|
}{
|
||||||
|
{nil, 0, nil},
|
||||||
|
{float32(123.5), 123.5, nil},
|
||||||
|
{"123.456", 123.456, nil},
|
||||||
|
{uint(123), 123, nil},
|
||||||
|
{uint8(123), 123, nil},
|
||||||
|
{uint16(123), 123, nil},
|
||||||
|
{uint32(123), 123, nil},
|
||||||
|
{uint64(123), 123, nil},
|
||||||
|
{int(123), 123, nil},
|
||||||
|
{int8(123), 123, nil},
|
||||||
|
{int16(123), 123, nil},
|
||||||
|
{int32(123), 123, nil},
|
||||||
|
{int64(123), 123, nil},
|
||||||
|
{complex64(1 + 2i), 1, nil},
|
||||||
|
{complex128(1 + 2i), 1, nil},
|
||||||
|
{true, 1, nil},
|
||||||
|
{false, 0, nil},
|
||||||
|
{(*bool)(nil), 0, nil},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
f, err := toFloat64(tc.value)
|
||||||
|
if f != tc.expected || err != tc.expectedErr {
|
||||||
|
t.Errorf("toFloat64(%v) = (%v, %v), expected (%v, %v)", tc.value, f, err, tc.expected, tc.expectedErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
f2, err2 := toFloat64Reflect(tc.value)
|
||||||
|
if f != tc.expected || err2 != tc.expectedErr {
|
||||||
|
t.Errorf("toFloat64Reflect(%v) = (%v, %v), expected (%v, %v)", tc.value, f2, err2, tc.expected, tc.expectedErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestToFloat64Pointer(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
input interface{}
|
||||||
|
expectedValue float64
|
||||||
|
expectedError error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "nil input",
|
||||||
|
input: nil,
|
||||||
|
expectedValue: 0,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "float32 pointer input",
|
||||||
|
input: float32Ptr(12.2),
|
||||||
|
expectedValue: 12.199999809265137,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "float64 pointer input",
|
||||||
|
input: float64Ptr(56.78),
|
||||||
|
expectedValue: 56.78,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid string input",
|
||||||
|
input: stringPtr("abc"),
|
||||||
|
expectedValue: 0,
|
||||||
|
expectedError: go_easy_utils.ErrSyntax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid string input",
|
||||||
|
input: stringPtr("123.45"),
|
||||||
|
expectedValue: 123.45,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "uint pointer input",
|
||||||
|
input: uintPtr(10),
|
||||||
|
expectedValue: 10,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "uint8 pointer input",
|
||||||
|
input: uint8Ptr(20),
|
||||||
|
expectedValue: 20,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "uint16 pointer input",
|
||||||
|
input: uint16Ptr(30),
|
||||||
|
expectedValue: 30,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "uint32 pointer input",
|
||||||
|
input: uint32Ptr(40),
|
||||||
|
expectedValue: 40,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "uint64 pointer input",
|
||||||
|
input: uint64Ptr(50),
|
||||||
|
expectedValue: 50,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "int pointer input",
|
||||||
|
input: intPtr(-60),
|
||||||
|
expectedValue: -60,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "int8 pointer input",
|
||||||
|
input: int8Ptr(-70),
|
||||||
|
expectedValue: -70,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "int16 pointer input",
|
||||||
|
input: int16Ptr(-80),
|
||||||
|
expectedValue: -80,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "int32 pointer input",
|
||||||
|
input: int32Ptr(-90),
|
||||||
|
expectedValue: -90,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "int64 pointer input",
|
||||||
|
input: int64Ptr(-100),
|
||||||
|
expectedValue: -100,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "complex64 pointer input",
|
||||||
|
input: complex64Ptr(complex(1, 2)),
|
||||||
|
expectedValue: 1,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "complex128 pointer input",
|
||||||
|
input: complex128Ptr(complex(3, 4)),
|
||||||
|
expectedValue: 3,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bool pointer input - true",
|
||||||
|
input: boolPtr(true),
|
||||||
|
expectedValue: 1,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bool pointer input - false",
|
||||||
|
input: boolPtr(false),
|
||||||
|
expectedValue: 0,
|
||||||
|
expectedError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unsupported input type",
|
||||||
|
input: "unsupported",
|
||||||
|
expectedValue: 0,
|
||||||
|
expectedError: go_easy_utils.ErrSyntax,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
actualValue, actualError := toFloat64(tc.input)
|
||||||
|
|
||||||
|
if actualError != tc.expectedError {
|
||||||
|
t.Errorf("Expected(name:%s) error: %v, but got: %v", tc.name, tc.expectedError, actualError)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(actualValue, tc.expectedValue) {
|
||||||
|
t.Errorf("Expected value: %v, but got: %v", tc.expectedValue, actualValue)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reflect
|
||||||
|
actualValue2, actualError2 := toFloat64Reflect(tc.input)
|
||||||
|
|
||||||
|
if actualError2 != tc.expectedError {
|
||||||
|
t.Errorf("Expected(name:%s) error: %v, but got: %v", tc.name, tc.expectedError, actualError2)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !reflect.DeepEqual(actualValue2, tc.expectedValue) {
|
||||||
|
t.Errorf("Expected value: %v, but got: %v", tc.expectedValue, actualValue2)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func float32Ptr(v float32) *float32 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func float64Ptr(v float64) *float64 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringPtr(v string) *string {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func uintPtr(v uint) *uint {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func uint8Ptr(v uint8) *uint8 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func uint16Ptr(v uint16) *uint16 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func uint32Ptr(v uint32) *uint32 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func uint64Ptr(v uint64) *uint64 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func intPtr(v int) *int {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func int8Ptr(v int8) *int8 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func int16Ptr(v int16) *int16 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func int32Ptr(v int32) *int32 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func int64Ptr(v int64) *int64 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func complex64Ptr(v complex64) *complex64 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func complex128Ptr(v complex128) *complex128 {
|
||||||
|
return &v
|
||||||
|
}
|
||||||
|
|
||||||
|
func boolPtr(v bool) *bool {
|
||||||
|
return &v
|
||||||
|
}
|
168
jsonUtil/to_int.go
Normal file
168
jsonUtil/to_int.go
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jefferyjob/go-easy-utils"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toInt64(i interface{}) (int64, error) {
|
||||||
|
if i == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
i = reflect.ValueOf(i).Elem().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := i.(type) {
|
||||||
|
case bool:
|
||||||
|
if v {
|
||||||
|
return 1, nil
|
||||||
|
}
|
||||||
|
return 0, nil
|
||||||
|
case uint:
|
||||||
|
return int64(v), nil
|
||||||
|
case uint8:
|
||||||
|
return int64(v), nil
|
||||||
|
case uint16:
|
||||||
|
return int64(v), nil
|
||||||
|
case uint32:
|
||||||
|
return int64(v), nil
|
||||||
|
case uint64:
|
||||||
|
return int64(v), nil
|
||||||
|
case float32:
|
||||||
|
return int64(v), nil
|
||||||
|
case float64:
|
||||||
|
return int64(v), nil
|
||||||
|
case complex64:
|
||||||
|
return int64(real(v)), nil
|
||||||
|
case complex128:
|
||||||
|
return int64(real(v)), nil
|
||||||
|
case string:
|
||||||
|
intValue, err := strconv.ParseInt(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, go_easy_utils.ErrSyntax
|
||||||
|
}
|
||||||
|
return intValue, nil
|
||||||
|
case int:
|
||||||
|
return int64(v), nil
|
||||||
|
case int8:
|
||||||
|
return int64(v), nil
|
||||||
|
case int16:
|
||||||
|
return int64(v), nil
|
||||||
|
case int32:
|
||||||
|
return int64(v), nil
|
||||||
|
case int64:
|
||||||
|
return v, nil
|
||||||
|
//case *bool:
|
||||||
|
// if v == nil {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// if *v {
|
||||||
|
// return 1, nil
|
||||||
|
// }
|
||||||
|
// return 0, nil
|
||||||
|
//case *uint:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *uint8:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *uint16:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *uint32:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *uint64:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *float32:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *float64:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *complex64:
|
||||||
|
// if v == nil {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return int64(real(*v)), nil
|
||||||
|
//case *complex128:
|
||||||
|
// if v == nil {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return int64(real(*v)), nil
|
||||||
|
//case *string:
|
||||||
|
// if v == nil {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// intValue, err := strconv.ParseInt(*v, 10, 64)
|
||||||
|
// if err != nil {
|
||||||
|
// return 0, go_easy_utils.ErrSyntax
|
||||||
|
// }
|
||||||
|
// return intValue, nil
|
||||||
|
//case *int:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *int8:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *int16:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *int32:
|
||||||
|
// return int64(*v), nil
|
||||||
|
//case *int64:
|
||||||
|
// return *v, nil
|
||||||
|
default:
|
||||||
|
return 0, go_easy_utils.ErrType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toInt64Reflect(i interface{}) (int64, error) {
|
||||||
|
if i == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查解引用后的值是否为 nil
|
||||||
|
if reflect.ValueOf(i).Kind() == reflect.Ptr && reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v := reflect.ValueOf(i)
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
v = reflect.ValueOf(i).Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
return int64(v.Float()), nil
|
||||||
|
case reflect.String:
|
||||||
|
intValue, err := strconv.ParseInt(v.String(), 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, go_easy_utils.ErrSyntax
|
||||||
|
}
|
||||||
|
return intValue, nil
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return v.Int(), nil
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return int64(v.Uint()), nil
|
||||||
|
case reflect.Complex64:
|
||||||
|
return int64(real(v.Complex())), nil
|
||||||
|
case reflect.Complex128:
|
||||||
|
return int64(real(v.Complex())), nil
|
||||||
|
case reflect.Bool:
|
||||||
|
if v.Bool() {
|
||||||
|
return 1, nil
|
||||||
|
} else {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
//case reflect.Ptr:
|
||||||
|
// if v.IsNil() {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return toInt64Reflect(v.Elem().Interface())
|
||||||
|
default:
|
||||||
|
return 0, go_easy_utils.ErrType
|
||||||
|
}
|
||||||
|
}
|
54
jsonUtil/to_int_test.go
Normal file
54
jsonUtil/to_int_test.go
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jefferyjob/go-easy-utils"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestToInt64(t *testing.T) {
|
||||||
|
var tests = []struct {
|
||||||
|
input interface{}
|
||||||
|
expected int64
|
||||||
|
err error
|
||||||
|
}{
|
||||||
|
{"123", 123, nil},
|
||||||
|
{"-234", -234, nil},
|
||||||
|
{345, 345, nil},
|
||||||
|
{-456, -456, nil},
|
||||||
|
{int8(12), 12, nil},
|
||||||
|
{int16(1238), 1238, nil},
|
||||||
|
{int32(1239), 1239, nil},
|
||||||
|
{int64(1230), 1230, nil},
|
||||||
|
{uint(1231), 1231, nil},
|
||||||
|
{uint8(123), 123, nil},
|
||||||
|
{uint16(1232), 1232, nil},
|
||||||
|
{uint32(1233), 1233, nil},
|
||||||
|
{uint64(1234), 1234, nil},
|
||||||
|
{float32(12.45), 12, nil},
|
||||||
|
{float64(123.45), 123, nil},
|
||||||
|
{true, 1, nil},
|
||||||
|
{false, 0, nil},
|
||||||
|
{complex64(1 + 2i), 1, nil},
|
||||||
|
{complex128(1 + 2i), 1, nil},
|
||||||
|
{nil, 0, nil},
|
||||||
|
{"not a number", 0, go_easy_utils.ErrSyntax},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
actual, err := toInt64(tt.input)
|
||||||
|
if err != tt.err {
|
||||||
|
t.Errorf("toInt64(%v): expected error %v, actual error %v", tt.input, tt.err, err)
|
||||||
|
}
|
||||||
|
if actual != tt.expected {
|
||||||
|
t.Errorf("toInt64(%v): expected %v, actual %v", tt.input, tt.expected, actual)
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err = toInt64Reflect(tt.input)
|
||||||
|
if err != tt.err {
|
||||||
|
t.Errorf("toInt64(%v): expected error %v, actual error %v", tt.input, tt.err, err)
|
||||||
|
}
|
||||||
|
if actual != tt.expected {
|
||||||
|
t.Errorf("toInt64(%v): expected %v, actual %v", tt.input, tt.expected, actual)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
184
jsonUtil/to_string.go
Normal file
184
jsonUtil/to_string.go
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toString(i interface{}) string {
|
||||||
|
if i == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
i = reflect.ValueOf(i).Elem().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := i.(type) {
|
||||||
|
case string:
|
||||||
|
return v
|
||||||
|
case int:
|
||||||
|
return strconv.Itoa(v)
|
||||||
|
case int8:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int16:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int32:
|
||||||
|
return strconv.FormatInt(int64(v), 10)
|
||||||
|
case int64:
|
||||||
|
return strconv.FormatInt(v, 10)
|
||||||
|
case uint:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint8:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint16:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint32:
|
||||||
|
return strconv.FormatUint(uint64(v), 10)
|
||||||
|
case uint64:
|
||||||
|
return strconv.FormatUint(v, 10)
|
||||||
|
case float32:
|
||||||
|
return strconv.FormatFloat(float64(v), 'f', -1, 32)
|
||||||
|
case float64:
|
||||||
|
return strconv.FormatFloat(v, 'f', -1, 64)
|
||||||
|
case complex64:
|
||||||
|
return fmt.Sprintf("(%g+%gi)", real(v), imag(v))
|
||||||
|
case complex128:
|
||||||
|
return fmt.Sprintf("(%g+%gi)", real(v), imag(v))
|
||||||
|
case bool:
|
||||||
|
return strconv.FormatBool(v)
|
||||||
|
//case *string:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return *v
|
||||||
|
//case *int:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.Itoa(*v)
|
||||||
|
//case *int8:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatInt(int64(*v), 10)
|
||||||
|
//case *int16:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatInt(int64(*v), 10)
|
||||||
|
//case *int32:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatInt(int64(*v), 10)
|
||||||
|
//case *int64:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatInt(*v, 10)
|
||||||
|
//case *uint:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatUint(uint64(*v), 10)
|
||||||
|
//case *uint8:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatUint(uint64(*v), 10)
|
||||||
|
//case *uint16:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatUint(uint64(*v), 10)
|
||||||
|
//case *uint32:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatUint(uint64(*v), 10)
|
||||||
|
//case *uint64:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatUint(*v, 10)
|
||||||
|
//case *float32:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatFloat(float64(*v), 'f', -1, 32)
|
||||||
|
//case *float64:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatFloat(*v, 'f', -1, 64)
|
||||||
|
//case *complex64:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return fmt.Sprintf("(%g+%gi)", real(*v), imag(*v))
|
||||||
|
//case *complex128:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return fmt.Sprintf("(%g+%gi)", real(*v), imag(*v))
|
||||||
|
//case *bool:
|
||||||
|
// if v == nil {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return strconv.FormatBool(*v)
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toStringReflect(i interface{}) string {
|
||||||
|
if i == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查解引用后的值是否为 nil
|
||||||
|
if reflect.ValueOf(i).Kind() == reflect.Ptr && reflect.ValueOf(i).IsNil() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
v := reflect.ValueOf(i)
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
v = reflect.ValueOf(i).Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.String:
|
||||||
|
return v.String()
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
return strconv.FormatInt(v.Int(), 10)
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return strconv.FormatUint(v.Uint(), 10)
|
||||||
|
case reflect.Float32:
|
||||||
|
return strconv.FormatFloat(v.Float(), 'f', -1, 32)
|
||||||
|
case reflect.Float64:
|
||||||
|
return strconv.FormatFloat(v.Float(), 'f', -1, 64)
|
||||||
|
case reflect.Complex64:
|
||||||
|
return fmt.Sprintf("(%g+%gi)", real(v.Complex()), imag(v.Complex()))
|
||||||
|
case reflect.Complex128:
|
||||||
|
return fmt.Sprintf("(%g+%gi)", real(v.Complex()), imag(v.Complex()))
|
||||||
|
case reflect.Bool:
|
||||||
|
return strconv.FormatBool(v.Bool())
|
||||||
|
//case reflect.Ptr:
|
||||||
|
// if v.IsNil() {
|
||||||
|
// return ""
|
||||||
|
// }
|
||||||
|
// return toStringReflect(v.Elem().Interface())
|
||||||
|
default:
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
}
|
41
jsonUtil/to_string_test.go
Normal file
41
jsonUtil/to_string_test.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestToString(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
value interface{}
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"nil", nil, ""},
|
||||||
|
{"string", "hello", "hello"},
|
||||||
|
{"int", 42, "42"},
|
||||||
|
{"int8", int8(42), "42"},
|
||||||
|
{"int16", int16(42), "42"},
|
||||||
|
{"int32", int32(42), "42"},
|
||||||
|
{"int64", int64(42), "42"},
|
||||||
|
{"uint", uint(42), "42"},
|
||||||
|
{"uint8", uint8(42), "42"},
|
||||||
|
{"uint16", uint16(42), "42"},
|
||||||
|
{"uint32", uint32(42), "42"},
|
||||||
|
{"uint64", uint64(42), "42"},
|
||||||
|
{"float32", float32(3.14159), "3.14159"},
|
||||||
|
{"float64", 3.14159, "3.14159"},
|
||||||
|
{"bool-true", true, "true"},
|
||||||
|
{"bool-false", false, "false"},
|
||||||
|
{"complex64", complex64(1 + 2i), "(1+2i)"},
|
||||||
|
{"complex128", complex128(3 + 4i), "(3+4i)"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if got := toString(tt.value); got != tt.want {
|
||||||
|
t.Errorf("ToString() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
|
||||||
|
if got := toStringReflect(tt.value); got != tt.want {
|
||||||
|
t.Errorf("ToString() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
223
jsonUtil/to_uint.go
Normal file
223
jsonUtil/to_uint.go
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jefferyjob/go-easy-utils"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func toUint64(i interface{}) (uint64, error) {
|
||||||
|
if i == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
i = reflect.ValueOf(i).Elem().Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v := i.(type) {
|
||||||
|
case float32:
|
||||||
|
if v < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(v), nil
|
||||||
|
case float64:
|
||||||
|
if v < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(v), nil
|
||||||
|
case complex64:
|
||||||
|
if real(v) < 0 || imag(v) < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(real(v)), nil
|
||||||
|
case complex128:
|
||||||
|
if real(v) < 0 || imag(v) < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(real(v)), nil
|
||||||
|
case string:
|
||||||
|
intValue, err := strconv.ParseUint(v, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, go_easy_utils.ErrSyntax
|
||||||
|
}
|
||||||
|
return intValue, nil
|
||||||
|
case bool:
|
||||||
|
if v {
|
||||||
|
return 1, nil
|
||||||
|
} else {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
case uint:
|
||||||
|
return uint64(v), nil
|
||||||
|
case uint8:
|
||||||
|
return uint64(v), nil
|
||||||
|
case uint16:
|
||||||
|
return uint64(v), nil
|
||||||
|
case uint32:
|
||||||
|
return uint64(v), nil
|
||||||
|
case uint64:
|
||||||
|
return v, nil
|
||||||
|
case int:
|
||||||
|
if v < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(v), nil
|
||||||
|
case int8:
|
||||||
|
if v < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(v), nil
|
||||||
|
case int16:
|
||||||
|
if v < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(v), nil
|
||||||
|
case int32:
|
||||||
|
if v < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(v), nil
|
||||||
|
case int64:
|
||||||
|
if v < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(v), nil
|
||||||
|
//case *float32:
|
||||||
|
// if *v < 0 {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *float64:
|
||||||
|
// if *v < 0 {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *complex64:
|
||||||
|
// if real(*v) < 0 || imag(*v) < 0 {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return uint64(real(*v)), nil
|
||||||
|
//case *complex128:
|
||||||
|
// if real(*v) < 0 || imag(*v) < 0 {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return uint64(real(*v)), nil
|
||||||
|
//case *string:
|
||||||
|
// intValue, err := strconv.ParseUint(*v, 10, 64)
|
||||||
|
// if err != nil {
|
||||||
|
// return 0, go_easy_utils.ErrSyntax
|
||||||
|
// }
|
||||||
|
// return intValue, nil
|
||||||
|
//case *bool:
|
||||||
|
// if *v {
|
||||||
|
// return 1, nil
|
||||||
|
// } else {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
//case *uint:
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *uint8:
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *uint16:
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *uint32:
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *uint64:
|
||||||
|
// return *v, nil
|
||||||
|
//case *int:
|
||||||
|
// if *v < 0 {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *int8:
|
||||||
|
// if *v < 0 {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *int16:
|
||||||
|
// if *v < 0 {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *int32:
|
||||||
|
// if *v < 0 {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return uint64(*v), nil
|
||||||
|
//case *int64:
|
||||||
|
// if *v < 0 {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return uint64(*v), nil
|
||||||
|
default:
|
||||||
|
return 0, go_easy_utils.ErrType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func toUint64Reflect(i interface{}) (uint64, error) {
|
||||||
|
if i == nil {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查解引用后的值是否为 nil
|
||||||
|
if reflect.ValueOf(i).Kind() == reflect.Ptr && reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
v := reflect.ValueOf(i)
|
||||||
|
// 处理指针类型
|
||||||
|
if reflect.TypeOf(i).Kind() == reflect.Ptr {
|
||||||
|
if reflect.ValueOf(i).IsNil() {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
v = reflect.ValueOf(i).Elem()
|
||||||
|
}
|
||||||
|
|
||||||
|
switch v.Kind() {
|
||||||
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
|
||||||
|
return v.Uint(), nil
|
||||||
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
||||||
|
intValue := v.Int()
|
||||||
|
if intValue < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(intValue), nil
|
||||||
|
case reflect.Float32, reflect.Float64:
|
||||||
|
floatValue := v.Float()
|
||||||
|
if floatValue < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(floatValue), nil
|
||||||
|
case reflect.Complex64, reflect.Complex128:
|
||||||
|
realValue := real(v.Complex())
|
||||||
|
if realValue < 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return uint64(realValue), nil
|
||||||
|
case reflect.String:
|
||||||
|
strValue := v.String()
|
||||||
|
uintValue, err := strconv.ParseUint(strValue, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, go_easy_utils.ErrSyntax
|
||||||
|
}
|
||||||
|
return uintValue, nil
|
||||||
|
case reflect.Bool:
|
||||||
|
if v.Bool() {
|
||||||
|
return 1, nil
|
||||||
|
} else {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
//case reflect.Ptr, reflect.Interface:
|
||||||
|
// if v.IsNil() {
|
||||||
|
// return 0, nil
|
||||||
|
// }
|
||||||
|
// return toUint64(v.Elem().Interface())
|
||||||
|
default:
|
||||||
|
return 0, go_easy_utils.ErrType
|
||||||
|
}
|
||||||
|
}
|
128
jsonUtil/to_uint_test.go
Normal file
128
jsonUtil/to_uint_test.go
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
package jsonUtil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jefferyjob/go-easy-utils"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestToUint64(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input interface{}
|
||||||
|
want uint64
|
||||||
|
wantError error
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Test uint8",
|
||||||
|
input: uint8(42),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test uint16",
|
||||||
|
input: uint16(42),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test uint32",
|
||||||
|
input: uint32(42),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test uint64",
|
||||||
|
input: uint64(42),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test int8",
|
||||||
|
input: int8(42),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test int16",
|
||||||
|
input: int16(42),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test int32",
|
||||||
|
input: int32(42),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test int64",
|
||||||
|
input: int64(42),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test float32",
|
||||||
|
input: float32(42.0),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test float64",
|
||||||
|
input: float64(42.0),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test complex64",
|
||||||
|
input: complex64(complex(42, 0)),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test complex128",
|
||||||
|
input: complex128(complex(42, 0)),
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test string",
|
||||||
|
input: "42",
|
||||||
|
want: 42,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test invalid string",
|
||||||
|
input: "not a number",
|
||||||
|
wantError: go_easy_utils.ErrSyntax,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test nil pointer",
|
||||||
|
input: (*int)(nil),
|
||||||
|
want: 0,
|
||||||
|
wantError: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test bool true",
|
||||||
|
input: true,
|
||||||
|
want: 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test bool false",
|
||||||
|
input: false,
|
||||||
|
want: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Test invalid type",
|
||||||
|
input: make(chan int),
|
||||||
|
wantError: go_easy_utils.ErrType,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := toUint64(tt.input)
|
||||||
|
if err != tt.wantError {
|
||||||
|
t.Errorf("toUint64(%v) error = %v, wantError %v", tt.input, err, tt.wantError)
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("toUint64(%v) = %v, want %v", tt.input, got, tt.want)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reflect
|
||||||
|
got2, err2 := toUint64Reflect(tt.input)
|
||||||
|
if err2 != tt.wantError {
|
||||||
|
t.Errorf("toUint64Reflect(%v) error = %v, wantError %v", tt.input, err2, tt.wantError)
|
||||||
|
}
|
||||||
|
if got2 != tt.want {
|
||||||
|
t.Errorf("toUint64Reflect(%v) = %v, want %v", tt.input, got2, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user