go开发中过度使用mapinterface{}?
在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《go开发中过度使用mapinterface{}?》,聊聊,希望可以帮助到正在努力赚钱的你。
我的大部分开发经验来自 php 和 javascript 等动态类型语言。通过在 golang 中重新创建一些旧的 php/javascript rest api,我已经练习 golang 大约一个月了。我觉得大多数时候我并没有以 golang 的方式做事。或者更一般地说,我不习惯使用强类型语言。我觉得我过度使用了 map[string]interface{}
及其片段来包装来自 http 请求的数据或作为 json http 输出发出的数据。那么我想知道的是,我要描述的内容是否违背了golang的开发理念?或者如果我违反了强类型语言的开发原则?
目前,我用 golang 重写的 rest api 程序流程大约 90% 都可以通过这 5 个步骤来描述。
第 1 步 - 接收数据
我从 http.request.parseform()
接收 http 表单数据,格式为 formvals := map[string][]string
。有时我会存储需要解组的序列化 json 对象,例如 jsonuserinfo := json.unmarshal(formvals["user_information"][0]) /* 给出一些复杂的 json 对象 */
。
第 2 步 - 验证数据
我对 formvals
进行验证,以确保在 sql 查询中使用它之前所有数据值都是我所期望的。我将所有内容视为字符串,然后使用 regex 来确定字符串格式和业务逻辑是否有效(例如 isemail、isnumeric、isfloat、iscaslcompliant、iseligibleforvoting、islibrarycardexpired 等)。我已经为这些类型的验证编写了自己的正则表达式和自定义函数
第 3 步 - 将数据绑定到 sql 查询
我使用golang的database/sql.db
来获取我的formvals并将它们绑定到我的查询和执行函数,例如query("select * from tbluser where user_id = ?, user_birthday > ? ",formvals["user_id"][ 0], jsonuserinfo["生日"])
.我从不关心我作为要绑定的参数提供的数据类型,因此它们可能都是字符串。我相信上面步骤中的验证已确定它们可以用于 sql。
第 4 步 - 将 sql 结果绑定到 []map[string]interface{}{}
我 scan()
将查询结果写入 sqlresult := []map[string]interface{}{}
因为我不关心值类型是否为 null、字符串、浮点数、整数或其他类型。因此 sqlresult
的架构可能如下所示:
sqlresult => [0] { "user_id":"1" "user_name":"bob smith" "age":"45" "weight":"34.22" }, [1] { "user_id":"2" "user_name":"jane do" "age":nil "weight":"22.22" }
我编写了自己的急切加载函数,以便可以绑定更多信息,例如 eagerload("tbladdress", "join on tbladdress.user_id",&sqlresult)
,然后使用 []map 类型的更多信息填充
,如下所示:sqlresult
[string]interface{}{}
sqlResult => [0] { "user_id":"1" "user_name":"Bob Smith" "age":"45" "weight":"34.22" "addresses"=> [0] { "type":"home" "address1":"56 Front Street West" "postal":"L3L3L3" "lat":"34.3422242" "lng":"34.5523422" } [1] { "type":"work" "address1":"5 Kennedy Avenue" "postal":"L3L3L3" "lat":"34.3422242" "lng":"34.5523422" } }, [1] { "user_id":"2" "user_name":"Jane Do" "age":nil "weight":"22.22" "addresses"=> [0] { "type":"home" "address1":"56 Front Street West" "postal":"L3L3L3" "lat":"34.3422242" "lng":"34.5523422" } }
第 5 步 - json 编组并发送 http 响应
然后我执行 http.responsewriter.write(json.marshal(sqlresult))
并为我的 rest api 输出数据
最近,我一直在重新审视带有代码示例的文章,这些代码示例在我本来会使用 map[string]interface{}
的地方使用结构。例如,我想使用其他 golang 开发人员会使用的更标准的方法来重构步骤 2。所以我找到了这个https://godoc.org/gopkg.in/go-演示/validator.v9,除了它的所有示例都是结构体。我还注意到,大多数谈论 database/sql
的博客都会将其 sql 结果扫描到类型化变量或具有类型化属性的结构中,而不是我的步骤 4,后者只是将所有内容放入 map[string]interface{}
因此,我开始写这个问题。我觉得 map[string] 接口{}
非常有用,因为大多数时候,我并不真正关心数据是什么,它让我可以在步骤 4 中自由地在我之前构建任何数据模式。将其转储为 json http 响应。我用尽可能少的代码来完成这一切。但这意味着我的代码还没有准备好利用 go 的验证工具,而且它似乎不符合 golang 社区的做事方式。
所以我的问题是,其他 golang 开发人员对步骤 2 和步骤 4 做了什么?特别是在第 4 步中……golang 开发人员真的鼓励通过结构和强类型属性指定数据模式吗?他们是否还指定具有强类型属性的结构以及他们进行的每个急切加载调用?这看起来是不是代码冗长了很多?
解决方案
这实际上取决于需求,就像您所说的那样,您不需要处理来自请求或 sql 结果的 json 。然后您可以轻松解组到 interface{}
。并编组来自 sql 结果的 json。
对于第 2 步
golang 有一个库,用于验证结构体,用于使用内部字段的标签来解组 json。
https://github.com/go-playground/validator
type test struct { field `validate:"max=10,min=1"` } // max will be checked then min
你也可以去godoc获取validation library。这是使用struct标签验证json值的非常好的实现。
对于第 4 步
大多数时候,如果我们知道 json 的格式和数据,我们就会使用结构。因为它为我们提供了对数据类型和其他功能的更多控制。例如,如果您想要清空 json 字段,而您的 json 中不需要它。您应该将 struct 与 _
json 标记一起使用。
现在你已经说过你不关心来自sql的结果是否为空。但如果你再次这样做,就会涉及到使用 struct。您可以使用 sql.NullTypes
将结果扫描到结构中。如果您想在发送响应时 marshaling
数据时省略 json 对象,也可以为 omitempty
提供 json 标记。
结构体值编码为 json 对象。每个导出的结构体字段 成为对象的成员,使用字段名作为对象 键,除非由于下面给出的原因之一而省略该字段。
每个结构体字段的编码可以通过格式自定义 存储在结构字段标记中“json”键下的字符串。这 格式字符串给出字段的名称,后面可能跟着一个 以逗号分隔的选项列表。该名称可以为空,以便 指定选项而不覆盖默认字段名称。
“omitempty”选项指定应从 如果字段有空值,则编码,定义为 false、0、a nil 指针、nil 接口值以及任何空数组、切片、映射、 或字符串。
作为特殊情况,如果字段标记为“-”,则该字段始终为 省略。请注意,仍然可以使用以下命令生成名称为“-”的字段 标签“-,”。
json 标签示例
// Field appears in JSON as key "myName". Field int `json:"myName"` // Field appears in JSON as key "myName" and // the field is omitted from the object if its value is empty, // as defined above. Field int `json:"myName,omitempty"` // Field appears in JSON as key "Field" (the default), but // the field is skipped if empty. // Note the leading comma. Field int `json:",omitempty"` // Field is ignored by this package. Field int `json:"-"` // Field appears in JSON as key "-". Field int `json:"-,"`
您可以从 golang 规范 json marshal 中给出的上述信息进行分析。struct 对 json 提供了如此多的控制。这就是 golang 开发人员最有可能使用结构的原因。
现在,在使用 map[string]interface{}
时,当您不知道来自服务器的 json 结构或字段类型时,应该使用它。大多数 golang 开发人员都会尽可能坚持使用结构。
文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《go开发中过度使用mapinterface{}?》文章吧,也可关注golang学习网公众号了解相关技术文章。

- 上一篇
- 刷新 gin-gonic 中的静态文件

- 下一篇
- golang函数命名约定的例外情况
-
- Golang · Go问答 | 12个月前 |
- 在读取缓冲通道中的内容之前退出
- 139浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 戈兰岛的全球 GOPRIVATE 设置
- 204浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 如何将结构作为参数传递给 xml-rpc
- 325浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 如何用golang获得小数点以下两位长度?
- 477浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 如何通过 client-go 和 golang 检索 Kubernetes 指标
- 486浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 将多个“参数”映射到单个可变参数的习惯用法
- 439浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 将 HTTP 响应正文写入文件后出现 EOF 错误
- 357浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 结构中映射的匿名列表的“复合文字中缺少类型”
- 352浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- NATS Jetstream 的性能
- 101浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 如何将复杂的字符串输入转换为mapstring?
- 440浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 相当于GoLang中Java将Object作为方法参数传递
- 212浏览 收藏
-
- Golang · Go问答 | 12个月前 |
- 如何确保所有 goroutine 在没有 time.Sleep 的情况下终止?
- 143浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 笔灵AI生成答辩PPT
- 探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
- 16次使用
-
- 知网AIGC检测服务系统
- 知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
- 25次使用
-
- AIGC检测-Aibiye
- AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
- 30次使用
-
- 易笔AI论文
- 易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
- 42次使用
-
- 笔启AI论文写作平台
- 笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
- 35次使用
-
- GoLand调式动态执行代码
- 2023-01-13 502浏览
-
- 用Nginx反向代理部署go写的网站。
- 2023-01-17 502浏览
-
- Golang取得代码运行时间的问题
- 2023-02-24 501浏览
-
- 请问 go 代码如何实现在代码改动后不需要Ctrl+c,然后重新 go run *.go 文件?
- 2023-01-08 501浏览
-
- 如何从同一个 io.Reader 读取多次
- 2023-04-11 501浏览