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
网友评论