一、问题

在处理消息接收的时候,前段会传一个json,字段类型不定,其中一个里面userId字段是数组,所以后端在 map[string]interface{} 再解析后类型为[]interface{} 想直接转[]uint64 结果报错

golang中 []interface{}转[]uint64解决办法_字符串数组

二、解决问题

其他类似在转成接口的时候是非常好转的,但是由接口转其他类型还是有点问题的。在上面的问题中 数组里的每一项都是是接口类型 然后转成[]unit64 。就是要将里面的每一项都转成unit64。这里可以使用循环处理。

for _,userId := range userIds.([]uint64) {
print(userId)
}

其实这样做有问题 如果是下面的数据

var x []interface{}
x[1] = "121"
x[2] = 121
for _, userId := range x.([]uint64) {
print(userId)
}

肯定会报错的。因为x里的每一项都是interface所以range的后面如果要加类型 也只能

for _,userId := range userIds.([]interface{}) {
print(userId)
}

然后在循环里面处理每一项为uint64即可。在处理的时候可以实用反射,将原来里的每一项interface处理成string,然后处理int,再处理成uint64 。至于为啥不直接将interface处理成uint64 。

直接转的话interface可能会是其他的类型 比如float 然后直接转uint64就失败。如下例子

golang中 []interface{}转[]uint64解决办法_i++_02

有些类型之间是不可以直接转换的,需要使用断言。简单的方法 fmt.Sprint()等方法可以直接转成string,然后转成int就可以了。

userIdsStr := m.Converts(nil, reflect.ValueOf(userIds))
for _, userIdStr := range userIdsStr {
userId, _ := strconv.ParseInt(userIdStr, 10, 64)
list = append(list, uint64(userId))
}

Converts 方法就是将不同类型转换成string的数组,后续可根据下需要自行处理。

// @Title Converts
// @Description 遍历变量里所有数值到一个字符串数组
// @Param dst []string 原始数组
// @return v reflect.Value 变量的reflect.ValueOf() 值
// @return []string 字符串数组
func (b *BaseServer) Converts(dst []string, v reflect.Value) []string {
// Drill down to the concrete value
for v.Kind() == reflect.Interface {
v = v.Elem()
}
if v.Kind() == reflect.Slice {
// Convert each element of the slice.
for i := 0; i < v.Len(); i++ {
dst = b.Converts(dst, v.Index(i))
}
} else {
// Convert value to string and append to result
dst = append(dst, fmt.Sprint(v.Interface()))
}
return dst
}