笔者在最近的工作中开发网络业务接口的时候遇到了需要根据键值对的键对结构体中的成员进行排序然后进行序列化和加密的需求。
我使用如下的go代码来根据类型拼接字符串,发现有一些数据字段没有被拼接进去:
str, _ := sonic.Marshal(/*准备处理的一部分数据*/)
paramMap := make(map[string]interface{})
_ = sonic.Unmarshal(str, ¶mMap)
paramMap["time"] = time.Now().Unix()
// 省略其他数据字段
// go:
// 拼接字符串
var str string
for _, k := range key {
switch v := paraMap[k].(type) {
case string:
str += "string类型-- " + k + "=" + v + "\n"
case int64:
str += "int64类型-- " + k + "=" + strconv.FormatInt(v, 10) + "\n"
}
}
一、问题归因
1、go语言的接口类型interface{}可以存储任意类型
2、switch里面没有处理键值对赋值的默认的数据类型
二、go语言中键值对赋值、直接赋值默认的数据类型
1、int类型
paraMap := make(map[string]interface{})
// int类型
paraMap["id"] = 1
paraMap["age"] = 18
paraMap["phone"] = 11451411
整数直接赋值变量、键值对是int类型,在32位系统上int是32位的、64位系统上则是64位的。
2、int64类型(unix时间戳)
paraMap := make(map[string]interface{})
// unix时间戳,int64类型
paraMap["timeUnixInt64"] = time.Now().Unix()
3、string类型(值放在双引号内、fmt.Sprintf函数赋值)
paraMap := make(map[string]interface{})
// string类型
paraMap["name"] = "李四"
paraMap["address"] = "上北野泽"
// unix时间戳,string类型
paraMap["time"] = fmt.Sprintf("%d", time.Now().Unix())
4、float类型
paraMap := make(map[string]interface{})
// float64类型
paraMap["score"] = 11.45
5、time.Time类型
paraMap := make(map[string]interface{})
// 当前时间戳,time.Time类型
paraMap["nowTime"] = time.Now()
三、可以指定数据类型进行赋值
例如:
paraMap := make(map[string]interface{})
// 指定float32类型
paraMap["scoreFloat32"] = float32(1145)
四、输出结果
我们先在main函数中初始化这个map并调用排序函数
func main() {
paraMap := make(map[string]interface{})
// int类型
paraMap["id"] = 1
paraMap["age"] = 18
paraMap["phone"] = 11451411
// unix时间戳,int64类型
paraMap["timeUnixInt64"] = time.Now().Unix()
paraMap["name"] = "李四"
paraMap["address"] = "上北野泽"
// unix时间戳,字符串类型
paraMap["time"] = fmt.Sprintf("%d", time.Now().Unix())
// float64类型
paraMap["score"] = 11.45
// 指定float32类型
paraMap["scoreFloat32"] = float32(1145)
// 当前时间戳,time.Time类型
paraMap["nowTime"] = time.Now()
ksortStr := getStrByksort(paraMap)
fmt.Print(ksortStr)
}
然后在排序函数中按照键进行排序并拼接字符串
// 将map转化为按照键排序后的字符串
func getStrByksort(paraMap map[string]interface{}) string {
// 按键排序
var key []string
for k := range paraMap {
key = append(key, k)
}
sort.Strings(key)
// 拼接字符串
var str string
for _, k := range key {
switch v := paraMap[k].(type) {
case string:
str += "string类型-- " + k + "=" + v + "\n"
case int64:
str += "int64类型-- " + k + "=" + strconv.FormatInt(v, 10) + "\n"
case int:
str += "int类型-- " + k + "=" + strconv.Itoa(v) + "\n"
case float64:
str += "float64类型-- " + k + "=" + strconv.FormatFloat(v, 'f', -1, 64) + "\n"
case float32:
str += "float32类型-- " + k + "=" + strconv.FormatFloat(float64(v), 'f', -1, 32) + "\n"
case time.Time:
str += "time.Time类型-- " + k + "=" + v.String() + "\n"
default:
str += "其他类型-- " + k + "=" + fmt.Sprintf("%v", v) + "\n"
}
}
return str
}
最终的输出结果: