Golang Gin 实战(五):接收数组和 Map
source link: https://mp.weixin.qq.com/s/u4R5MZABcy-231g4_HDrdg
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
在 上一篇 Golang Gin 实战(四)| URL查询参数的获取和原理分析
文章中,因为文章篇幅问题, QueryArray
和 QueryMap
没有介绍,这篇文章继续。
QueryArray
在实际的业务开发中,我们有些业务多选的,比如一个活动有多个人参加,一个问题有多个答案等等,对于这类业务功能来说,如果是通过查询参数提交的,它们的URL大概这样 ?a=b&a=c&a=d
, key
值都一样,但是对应的 value
不一样。
这类URL查询参数,就是一个数组,那么在Gin中我们如何获取它们呢?
这里举个例子,比如有一份调查问卷,问我有哪些自媒体,我选择个人博客和微信公众号
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.JSON(200, c.QueryArray("media"))
})
r.Run(":8080")
}
运行代码,在浏览器里访问 http://localhost:8080/?media=blog&media=wechat
,会看到如下信息:
["blog","wechat"]
我们的自媒体信息,已经作为一个数组被输出了,非常简单,这样我们就可以很方便的处理多选的业务。
QueryArray
方法也有对应的 GetQueryArray
方法,区别在于返回对应的 key
是否存在,这里不再举例。
QueryArray
和 GetQueryArray
源代码实现已经在上一篇 Golang Gin 实战(四)| URL查询参数的获取和原理分析
分析了,这里不再赘述,大家可以再看下上一篇文章。
QueryMap
QueryMap
其实就是把满足一定格式的URL查询参数,转换为一个 map
,假设有a,b,c三个人,他们对应的id是123,456,789.那么用map的方式表示,这种格式类似于:
?ids[a]=123&ids[b]=456&ids[c]=789
从以上URL看,关键在于 key
,这个key必须符合 map
的定义, []
外面的必须相同,也就是 ids
这个 map
变量名, []
里面的,也就是 map
的key不能相同,这样就满足了 Gin
定义的把URL查询参数转换为 map
的格式定义。
r.GET("/map", func(c *gin.Context) {
c.JSON(200, c.QueryMap("ids"))
})
获取 map
的方法很简单,把 ids
作为 key
即可。现在运行代码,访问 http://localhost:8080/map?ids[a]=123&ids[b]=456&ids[c]=789
,就会看到如下信息:
{"a":"123","b":"456","c":"789"}
我们输入的信息,正好被我们打印出来了。
GetQueryMap
和 QueryMap
是一样的,只是返回了对应的 key
是否存在。
QueryMap 的原理
func (c *Context) QueryMap(key string) map[string]string {
dicts, _ := c.GetQueryMap(key)
return dicts
}
func (c *Context) GetQueryMap(key string) (map[string]string, bool) {
c.getQueryCache()
return c.get(c.queryCache, key)
}
QueryMap
是通过 GetQueryMap
,最终都是 c.get
这个方法实现,我们只需要分析 c.get
就可以了。注意这里同样用到了 getQueryCache
进行缓存提高性能。
func (c *Context) get(m map[string][]string, key string) (map[string]string, bool) {
dicts := make(map[string]string)
exist := false
for k, v := range m {
if i := strings.IndexByte(k, '['); i >= 1 && k[0:i] == key {
if j := strings.IndexByte(k[i+1:], ']'); j >= 1 {
exist = true
dicts[k[i+1:][:j]] = v[0]
}
}
}
return dicts, exist
}
这段实现代码看着比较绕,其实挺简单,它有两个参数,一个 m
其实就是缓存的所有查询参数键值对 queryCache
,另外一个就是我们要找的 key
因为 Gin
定义的map的URL特殊格式化,所以这里需要判断是否有 []
,如果有的话,并且 key
匹配,那么这个键值对就是我们需要找的,把它存在 dicts
即可,最终返回的是这个 dicts
。
这里等于是, Gin
帮我们做了包装,可以更好的把特殊格式的URL转为 map
,提升了我们使用的效率,不过这种方法不常用,如果有特别的需要可以使用。
小结
接收数组是比较常用的,但是 map
不常用。其实对于接收参数来说,不光我们可以从URL查询参数中获得,还可以从提交的表单(Form)中获得,它们的原理是大同小异的,使用方式也非常像,下一篇我们就介绍表单的使用和原理分析。
感谢新老朋友的转发、阅读和点赞支持,给大家抽个现金红包(点击参与),在看到50,下次抽奖金额翻倍!
我有几个的Go语言交流微信群,可以扫码关注公众号 flysnow_org
或者网站 https://www.flysnow.org/,加我好友,我拉你进来。
往期 精彩 回顾
Golang Gin 实战(四)| URL查询参数的获取和原理分析
Golang Gin 实战(二)| 简便的Restful API 实现
扫码关注
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK