golang json 序列化、反序列化 字符串反序列化成 m

2022-06-28  本文已影响0人  光剑书架上的书

json.Unmarshl 反序列化 : 将 json 字符串转为结构体

func Unmarshal(data []byte, v interface{}) error 

需求:将 json 字符串转为结构体
1)预先定义json对应的结构体类型;
2)调用 json.Unmarshl

func main() {
    // 这里反引号表示不转意,即为string类型
    resp := `{"code":0,"message":"success","grades":[{"gradeClass":"一年级","Score":{"chinese":99,"english":88}},{"gradeClass":"二年级","Score":{"chinese":100,"english":98}}]}`
    var stu Student
    err := json.Unmarshal([]byte(resp), &stu)
    if err != nil {
        log.Println(err)
    }
    log.Println(stu)
    // 2021/08/12 23:37:19 {0 success [{一年级 {99 88}} {二年级 {100 98}}]}
}

type Student struct {
    Code    int         `json:"code"`    // 使用tag,表示对应json的字段名
    Message string      `json:"message"`
    Grades  []GradeType `json:"grades"`  // 结构体类数组
}
type GradeType struct {
    GradeClass string `json:"gradeClass"`
    Score      ScoreType
}
type ScoreType struct {
    Chinese int `json:"chinese"`
    English int `json:"english"`
}

json 字符串反序列化成 map

    // 强转interface类型到string类型(注意: 不是 convert.ToJSONString)
    wordCloudJson := convert.ToString(data[0]["word_cloud_json"])

    words := make(map[string]interface{})
    err = json.Unmarshal([]byte(wordCloudJson), &words)
    if err != nil {
        logu.CtxError(ctx, error_code.ProcessError, "GetBrandWordCloud Unmarshal", "wordCloudJson:%v,error: %v", wordCloudJson, err)
        return result, err
    }

    for k, v := range words {
        result = append(result, &competition_detail.BrandWord{
            ProductPropertyValue: k,
            ProductFrequency:     convert.ToInt64(v),
        })
    }

    // 降序取 TOP 100
    top(&result, 100)

其中,func ToString(i interface{}) string 代码:

// ToString 强转interface类型到string类型
func ToString(i interface{}) string {
    v, _ := ToStringE(i)
    return v
}



// ToStringE 强转interface类型到string, 支持错误返回值
func ToStringE(i interface{}) (string, error) {
    i = indirectToStringerOrError(i)

    switch s := i.(type) {
    case string:
        return s, nil
    case bool:
        return strconv.FormatBool(s), nil
    case float64:
        return strconv.FormatFloat(s, 'f', -1, 64), nil
    case float32:
        return strconv.FormatFloat(float64(s), 'f', -1, 32), nil
    case int:
        return strconv.Itoa(s), nil
    case int64:
        return strconv.FormatInt(s, 10), nil
    case int32:
        return strconv.Itoa(int(s)), nil
    case int16:
        return strconv.FormatInt(int64(s), 10), nil
    case int8:
        return strconv.FormatInt(int64(s), 10), nil
    case uint:
        return strconv.FormatInt(int64(s), 10), nil
    case uint64:
        return strconv.FormatInt(int64(s), 10), nil
    case uint32:
        return strconv.FormatInt(int64(s), 10), nil
    case uint16:
        return strconv.FormatInt(int64(s), 10), nil
    case uint8:
        return strconv.FormatInt(int64(s), 10), nil
    case []byte:
        return string(s), nil
    case template.HTML:
        return string(s), nil
    case template.URL:
        return string(s), nil
    case template.JS:
        return string(s), nil
    case template.CSS:
        return string(s), nil
    case template.HTMLAttr:
        return string(s), nil
    case nil:
        return "", nil
    case fmt.Stringer:
        return s.String(), nil
    case error:
        return s.Error(), nil
    default:
        v := reflect.ValueOf(i)
        if method, ok := reflect.TypeOf(i).MethodByName("String"); ok && method.Type.NumIn() == 0 &&
            method.Type.NumOut() == 1 && method.Type.Out(0).Kind() == reflect.String {
            return method.Func.Call([]reflect.Value{v})[0].String(), nil
        }
        switch v.Kind() {
        case reflect.Func:
            fullName := runtime.FuncForPC(v.Pointer()).Name()
            ss := strings.Split(fullName, ".")
            if len(ss) > 0 {
                return ss[len(ss)-1], nil
            } else {
                return fullName, nil
            }
        case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
            return ToStringE(v.Uint())
        case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
            return ToStringE(v.Int())
        case reflect.Float64, reflect.Float32:
            return ToStringE(v.Float())
        case reflect.Bool:
            return ToStringE(v.Bool())
        case reflect.String:
            return v.String(), nil
        }
        return "", fmt.Errorf("unable to cast %#v of type %T to string", i, i)
    }
}


参考资料

https://blog.csdn.net/Sunny_Future/article/details/119656822

上一篇下一篇

猜你喜欢

热点阅读