json:你或许还不知道的使用的坑(三)续

本文详细介绍了Go语言中JSON反序列化时可能遇到的问题,包括科学计数法处理、null值处理、反序列化到接口、数组与切片的区别、map的key限制以及自定义反序列化策略等。通过示例代码和源码分析,揭示了Go JSON库的内在逻辑,帮助读者理解并避免相关陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、前言

其实本篇应该写的是json的反序列化,所以花了几个晚上看了下该部分源码,每次看都想睡觉。为什么呢?因为确实是太无聊了,我打赌这是我看过go源码中最无聊的逻辑,全篇都是一些状态的切换,要么是 if ... else ...,要么就是switch ... case ... case ...,头大。我也尝试画过流程图,但是这么多状态的切换,也不知道是什么力量支撑我画了2天时间,最后我放弃了-画出来没有丝毫意义。所以本篇我就源码层面顺着json:你或许还不知道的使用的坑(一)续写下反序列化可能会遇到的一些坑或者未知的使用方法。

tips:

  • 我在看的过程中也留了些注释,看兴趣的话可以去GitHub上去看看,也欢迎你的加入。
  • 所有代码在 The Go Playground都能看到。

二、内容

1.反序列化科学计数法

假如你有这么个json字符串,如何序列化呢?

{
   
	"Name": "zhangSan",
 	"Age": -0e+10000
}

注意Age字段的值并没有被双引号包围,所以go提供了一种类型json.Number专门用来装数字,包括科学计数法和普通数字。下面是我的结构体:

type User struct {
   
	Name string
	Age  json.Number
}

运行我的示例代码能得到正确结果:

{
   zhangSan -0e+10000}

2.value是null的注意

假如我有这么个json字符串:

	{
   
		"Name": null,
 		"Age": null
	}

且我的结构体是这样的:

    type User struct {
   
      Name string
      Age  map[string]string
    }

我的序列化代码如下:

	var san = User{
   
		Name: "aaa",
		Age:  map[string]string{
   "1": "1"},
	}
	err := json.Unmarshal(bytes, &san)
	if err != nil {
   
		fmt.Println("error:", err)
	} else {
   
		fmt.Println(san)
	}

你觉得打印结果会是神马样子的呢?

{
   aaa map[]}

会有点不可思议是吧?为什么Name的值没有改变,但是Age确被重新初始化了呢?
go的官方序列化代码如下:

	case 'n': // null
		// The main parser checks that only true and false can reach here,
		// but if this was a quoted string input, it could be anything.
		if fromQuoted && string(item) != "null" {
    // 字段有',string'标签,以n开头,必须是null
			d.saveError(fmt.Errorf("json: invalid use of ,string struct tag, trying to unmarshal %q into %v", item, v.Type()))
			break
		}
		switch v.Kind() {
   
		case reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice: // 设置给interface{},指针,map,切片一个初始化的值
			v.Set(reflect.Zero(v.Type()))
			
### 解决PyCharm无法加载Conda虚拟环境的方法 #### 配置设置 为了使 PyCharm 能够成功识别并使用 Conda 创建的虚拟环境,需确保 Anaconda 的路径已正确添加至系统的环境变量中[^1]。这一步骤至关重要,因为只有当 Python 解释器及其关联工具被加入 PATH 后,IDE 才能顺利找到它们。 对于 Windows 用户而言,在安装 Anaconda 时,默认情况下会询问是否将它添加到系统路径里;如果当时选择了否,则现在应该手动完成此操作。具体做法是在“高级系统设置”的“环境变量”选项内编辑 `Path` 变量,追加 Anaconda 安装目录下的 Scripts 文件夹位置。 另外,建议每次新建项目前都通过命令行先激活目标 conda env: ```bash conda activate myenvname ``` 接着再启动 IDE 进入工作区,这样有助于减少兼容性方面的问题发生概率。 #### 常见错误及修复方法 ##### 错误一:未发现任何解释器 症状表现为打开 PyCharm 新建工程向导页面找到由 Conda 构建出来的 interpreter 列表项。此时应前往 Preferences/Settings -> Project:...->Python Interpreter 下方点击齿轮图标选择 Add...按钮来指定自定义的位置。按照提示浏览定位到对应版本 python.exe 的绝对地址即可解决问题。 ##### 错误二:权限足导致 DLL 加载失败 有时即使指定了正确的解释器路径,仍可能遇到由于缺乏适当的操作系统级许可而引发的功能缺失现象。特别是涉及到调用某些特定类型的动态链接库 (Dynamic Link Library, .dll) 时尤为明显。因此拥有管理员身份执行相关动作显得尤为重要——无论是从终端还是图形界面触发创建新 venv 流程均如此处理能够有效规避此类隐患。 ##### 错误:网络连接异常引起依赖下载超时 部分开发者反馈过因网速慢或者其他因素造成 pip install 操作中途断开进而影响整个项目的初始化进度条卡住的情况。对此可尝试调整镜像源加速获取速度或是离线模式预先准备好所需资源包后再继步骤。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangshen023

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值