我们知道,go语言是一门强类型的语言,我们在某些时候可能需要再同一个api接口中接收和处理不同类型的参数, 这时我们就可以通过定义一个 any类型的请求参数来让gin框架帮我们接收和解析不同类型的请求参数。
下面我们就以接收任意类型的ids数据为例来演示gin框架中任意类型的请求参数接收和解析的方法
请求参数接收结构体定义
// 定义一个结构体,用来接收任意类型的id数据
type AnyIdsReq struct {Ids any `form:"ids"` // 这里的tag form:"ids" 是gin框架中用来接收表单名为ids的数据的
}
gin框架接收和解析任意类型 any / interface{} 参数示例
下面示例演示了gin框架里面接收任意类型的参数并转换为 []int64类型的示例,如果需要其他的类型,可以参考下面的模式, 进行相应的数据转换即可。 记着应用go语言里面类型转换的3大法宝即可,即:反射, 类型断言.(T) 和 .(type) 类型获取
func (a *parserApi) CheckUrl(c *ginx.XContext) {var req = &AnyIdsReq{}// 获取参数if err := c.ShouldBind(req); err != nil {// gin 参数绑定异常了。。。。。return}// 定义一个我们需要的数据类型变量idss := make([]int64, 0)// 通过反射获取反射类型rt:=reflect.TypeOf(req.Ids)// 根据不同的类型来解析数据,switch rt.Kind() {case reflect.Float64: // 这里注意int类型的数据json后会变成float64idss = append(idss, ToInt64(req.Ids))case reflect.Slice: // 数据是切片类型if iss,ok:=req.Ids.([]interface{});ok {for _, v := range iss {idss = append(idss, ToInt64(v))}}// 还需要处理其他的类型? 这里接着case 然后接着处理即可}// 到这里我们就将前端传递的参数,不管是当个值还是数组,这里都统一转换成了我们指定类型的数组 idss// ...... 其他逻辑
}
注意,gin框架请求参数的绑定和解析底层使用了json, 所以前端发送的int类型数据 会被转换为 float64类型, 我们在接收和处理any类型的数据的时候需要注意这点。
ToInt64 转换任意any/interface{}类型数据到int64类型
// ToInt64 转换任意any/interface{}类型数据到int64类型
func ToInt64(val interface{}) int64 {if val == nil {return 0}// .(type) 这个是一个固定用法,目的就是获取go语言的类型表示switch value := val.(type) {case int:return int64(value)case int8:return int64(value)case int16:return int64(value)case int32:return int64(value)case int64:return valuecase uint:return int64(value)case uint8:return int64(value)case uint16:return int64(value)case uint32:return int64(value)case uint64:return int64(value)case float32:return int64(value)case float64:return int64(value)case bool:if value {return 1}return 0case string:// 将value.(string)断言为字符串后解析为int64if v, err := strconv.ParseInt(value.(string), 16, 64); err == nil {return v}else{return 0}default:// 其他情况返回0 也可以自己处理return 0}
}
总结:
接收任意类型的参数的核心就是数据类型的转换,这里应用了go语言里面数据类型转换的3大法宝,反射,类型断言和类型获取。