返回顶部
首页 > 资讯 > 后端开发 > GO >Golang中JSON遇到的坑如何解决
  • 320
分享到

Golang中JSON遇到的坑如何解决

2023-07-05 06:07:45 320人浏览 八月长安
摘要

本篇内容主要讲解“golang中JSON遇到的坑如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Golang中jsON遇到的坑如何解决”吧!空指针会被解析成字符串"null&qu

本篇内容主要讲解“golangJSON遇到的坑如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习Golang中jsON遇到的坑如何解决”吧!

空指针会被解析成字符串"null"

type Person struct {Name stringAge  int}func main() {var p *Personbytes, err := json.Marshal(p)checkError(err)fmt.Printf("len:%d, result:%s\n", len(bytes), string(bytes))  // len:4, result:null}func checkError(err error) {if err != nil {fmt.Printf("err:%+v\n", err)}}

json.Marshal一个空指针的时候,得到的结果居然是"null"字符串,我以为是""或者报错。

还有个奇怪的坑

type Person struct {Name stringAge  int}func main() {var p *Persons := `null`err := json.Unmarshal([]byte(s), &p)checkError(err)fmt.Printf("p:%+v\n", p) // p:<nil>}

这个居然不报错,而是得到空指针p

如果把s随便换成其他字符串s := "abc",则报错:invalid character 'a' looking for beginning of value,之前我理解的是null对go来说应该跟abc没有差别,都是字符串。没想到他们是不一样的,下面来深究一下json.UnMarshal底层代码。

在UnMarshal之前它有个checkValid函数

func checkValid(data []byte, scan *scanner) error {scan.reset()for _, c := range data {scan.bytes++if scan.step(scan, c) == scanError {return scan.err}}if scan.eof() == scanError {return scan.err}return nil}

checkValid函数会check每一个字符,调用step函数,step初始值是stateBeginValue

// stateBeginValue is the state at the beginning of the input.func stateBeginValue(s *scanner, c byte) int {if isSpace(c) {return scanSkipSpace}switch c {case '{':s.step = stateBeginStringOrEmptyreturn s.pushParseState(c, parseObjecTKEy, scanBeginObject)case '[':s.step = stateBeginValueOrEmptyreturn s.pushParseState(c, parseArrayValue, scanBeginArray)case '"':s.step = stateInStringreturn scanBeginLiteralcase '-':s.step = stateNegreturn scanBeginLiteralcase '0': // beginning of 0.123s.step = state0return scanBeginLiteralcase 't': // beginning of trues.step = stateTreturn scanBeginLiteralcase 'f': // beginning of falses.step = stateFreturn scanBeginLiteralcase 'n': // beginning of nulls.step = stateNreturn scanBeginLiteral}if '1' <= c && c <= '9' { // beginning of 1234.5s.step = state1return scanBeginLiteral}return s.error(c, "looking for beginning of value")}

有这么一段代码,这是处理第一个字符的,发现它对第一个字符是n有特殊处理并且设置下一个字符处理函数为stateN

// stateN is the state after reading `n`.func stateN(s *scanner, c byte) int {if c == 'u' {s.step = stateNureturn scanContinue}return s.error(c, "in literal null (expecting 'u')")}

也就是下一个字符必须是u,再下一个字符处理函数为stateNu

// stateNu is the state after reading `nu`.func stateNu(s *scanner, c byte) int {if c == 'l' {s.step = stateNulreturn scanContinue}return s.error(c, "in literal null (expecting 'l')")}

也就是下一个字符必须是l,再下一个字符处理函数为stateNul

// stateNul is the state after reading `nul`.func stateNul(s *scanner, c byte) int {if c == 'l' {s.step = stateEndValuereturn scanContinue}return s.error(c, "in literal null (expecting 'l')")}

也就是下一个字符必须是l,再下一个字符处理函数为stateEndValue。

可见checkValid函数对true,false等都有特殊处理。使用时需要注意。

对于json.Marshal函数,通过调试发现它对空指针也有特殊处理

type ptrEncoder struct {elemEnc encoderFunc}func (pe ptrEncoder) encode(e *encodeState, v reflect.Value, opts encOpts) {if v.IsNil() {e.WriteString("null")return}if e.ptrLevel++; e.ptrLevel > startDetectinGCyclesAfter {// We're a large number of nested ptrEncoder.encode calls deep;// start checking if we've run into a pointer cycle.ptr := v.Interface()if _, ok := e.ptrSeen[ptr]; ok {e.error(&UnsupportedValueError{v, fmt.Sprintf("encountered a cycle via %s", v.Type())})}e.ptrSeen[ptr] = struct{}{}defer delete(e.ptrSeen, ptr)}pe.elemEnc(e, v.Elem(), opts)e.ptrLevel--}

如果是空指针则返回字符串"null",并且不会报错。

int类型会被解析成float64

type Person struct {Name stringAge  int}func main() {p := &Person{Name: "text",Age:  18,}bytes, err := json.Marshal(p)checkError(err)pMap := make(map[string]interface{})err = json.Unmarshal(bytes, &pMap)checkError(err)for k, v := range pMap {fmt.Printf("k:%s,v:%+v, vtype:%v\n", k, v, reflect.TypeOf(v))}}func checkError(err error) {if err != nil {fmt.Printf("err:%+v\n", err)}}

结果

k:Name,v:text, vtype:string
k:Age,v:18, vtype:float64

显然,Age类型变成了float64。会造成什么问题呢?当int大小超过6位的时候就变成了科学计数法 比如Age=1234567, 结果为

k:Name,v:text, vtype:string
k:Age,v:1.234567e+06, vtype:float64

这个时候如果直接将map更新到db,原本是int类型的字段变成了float类型,就报错了

到此,相信大家对“Golang中JSON遇到的坑如何解决”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

您可能感兴趣的文档:

--结束END--

本文标题: Golang中JSON遇到的坑如何解决

本文链接: https://lsjlt.com/news/350064.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Golang中JSON遇到的坑如何解决
    本篇内容主要讲解“Golang中JSON遇到的坑如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Golang中JSON遇到的坑如何解决”吧!空指针会被解析成字符串"null&qu...
    99+
    2023-07-05
  • Golang解析JSON遇到的坑及解决方法
    目录写在前面空指针会被解析成字符串"null"int类型会被解析成float64写在前面 在写go的时候经常用到序列化、反序列化,记录一下遇到过的坑。 空指针会被...
    99+
    2023-02-26
    Golang解析JSON Go 解析JSON Go JSON
  • springboot连接sqllite遇到的坑如何解决
    本篇内容主要讲解“springboot连接sqllite遇到的坑如何解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“springboot连接sqllite遇到的坑如何解决”吧!springbo...
    99+
    2023-07-02
  • vue+freemarker中遇到的坑及解决
    目录vue+freemarker遇到的坑在这个过程中遇到了几个坑freemarker的一些坑问题1.对空对象十分敏感2.freemarker中的${}与js中的${}冲突3.渲染数字...
    99+
    2024-04-02
  • @ConfigurationProperties遇到的坑及解决
    想着偷懒,直接使用@ConfigurationProperties(prefix="xxx")读取配置文件,不使用@Value("${xxx}")去一个一个的注入。 遇到的坑: 创...
    99+
    2024-04-02
  • springcloudoauth2feign遇到的坑及解决
    目录springcloudoauth2feign遇到的坑客户端模式基于springsecurityspringcloud微服务增加oauth2权限后feign调用报null一般是这样...
    99+
    2024-04-02
  • MyBatis+MyBatisPlus中遇到的坑怎么解决
    这篇文章主要介绍了MyBatis+MyBatisPlus中遇到的坑怎么解决的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇MyBatis+MyBatisPlus中遇到的坑怎么解决文章都会有所收获,下面我们一起来看...
    99+
    2023-07-05
  • 如何解决AngualrJs清除定时器遇到的坑
    这篇文章给大家分享的是有关如何解决AngualrJs清除定时器遇到的坑的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。angualrJs清除定时器爬坑之路:发现一个奇怪问题,放在自...
    99+
    2024-04-02
  • Feign+mybatisplus搭建项目遇到的坑如何解决
    这篇文章主要讲解了“Feign+mybatisplus搭建项目遇到的坑如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Feign+mybatisplus搭建项目遇到的坑如何解决”吧!出...
    99+
    2023-07-05
  • 解决在Unity中使用FairyGUI遇到的坑
    首先!首先!首先! 首先,我们由于历史问题,项目用的UI编辑器不是大众使用的GUI或者NGUI, 而是使用不知道算不算小众的FairyGUI,这个UI系统使用挺方便的,也提供了很多U...
    99+
    2024-04-02
  • 解决安装Oracle 11g 遇到的坑
    一.Win10下安装Oracle 11g 报错 信息 [INS-30131] 执行安装程序验证所需的初始设置失败解决:在CMD(管理员身份运行)中使用如下带权限的创建c盘共享命令:net share C$=...
    99+
    2024-04-02
  • 解决SpringBoot整合RocketMQ遇到的坑
    应用场景 在实现RocketMQ消费时,一般会用到@RocketMQMessageListener注解定义Group、Topic以及selectorExpression(数...
    99+
    2024-04-02
  • 解决slf4j 和 logback-classic遇到的坑
    slf4j 和 logback-classic遇到的坑 以前一直不注意日志的打印,最近项目需求需要用日志记录用时性能,集成日志时遇到的问题记录下。 问题一:服务器启动时提示未找到sl...
    99+
    2024-04-02
  • 解决springboot整合druid遇到的坑
    springboot整合druid的坑 项目环境 springboot 2.1.6.RELEASE jdk 1.8 pom.xml配置 <?xm...
    99+
    2024-04-02
  • 解决使用openpyxl时遇到的坑
    最近在用python处理Excel表格是遇到了一些问题 1, xlwt最多只能写入65536行数据, 所以在处理大批量数据的时候没法使用 2, openpyxl 这个库, 在使用的时...
    99+
    2024-04-02
  • SpringBoot遇到的坑@Qualifier报红的解决
    目录SpringBoot遇到的坑@Qualifier报红解决方法SpringBoot注解@Qualifier用法SpringBoot遇到的坑@Qualifier报红 今天写项目的时候...
    99+
    2024-04-02
  • 解决hive中导入text文件遇到的坑
    今天帮一同学导入一个excel数据,我把excel保存为txt格式,然后建表导入,失败!分隔符格式不匹配,无法导入!!!!怎么看两边都是\t,怎么不匹配呢? 做为程序员,最不怕的就是...
    99+
    2024-04-02
  • 解决Spring boot 整合Junit遇到的坑
    目录这是我在使用springboot整合Junit的时候遇到的坑1.在pom.xml中添加junit环境的依赖2.在src/test/java下建立测试类3.自己编写的启动类Spri...
    99+
    2024-04-02
  • vue使用mui遇到的坑及解决
    目录使用mui遇到的坑记录mui的js冲突了,有2种解决方法方法1方法2使用mui遇到的坑记录 主要用到webpack打包工具与mui,mint ui,其中mui有不少坑,在此记录 ...
    99+
    2024-04-02
  • springboot连接sqllite遇到的坑及解决
    目录springboot连接sqllite的坑springboot集成sqlite配置设置springboot集成sqlitespringboot连接sqllite的坑 2021-0...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作