• Golang 中空的切片转化成 JSON 后变为 null 的问题如何解决?


    目录

    问题

    原因

    小结


    问题

    在 Golang 中,经常需要将其他类型(例如 slice、map、struct 等类型)的数据转化为 JSON 格式。有时候转化的结果并不是预期中的,例如将一个空的切片转化为 JSON 时,会变成"null",而并非预期的"[]"。示例代码如下:

    1. package main
    2. import (
    3. "encoding/json"
    4. "fmt"
    5. )
    6. func main() {
    7. var res []string
    8. b, err := json.Marshal(res)
    9. if err != nil {
    10. panic(err)
    11. }
    12. fmt.Println(string(b))
    13. }

    运行示例看下结果:

    1. $ go run main.go
    2. null

    结果输出的值为 “null”,而并非预期中的 “[]”。

    原因

    上面示例代码中的 res 是通过 var 关键字来声明为字符串类型切片的,这样的切片称为零值切片,其值为 nil,无指向任何内存地址。其出现实标题中这种情况的切片就是零值切片,接下来介绍下零值切片和空切片。

    在 Golang 中,切片是一个长度可变的数组,有三个属性:指针、长度和容量。"零值切片"和"空切片"是两种特殊的切片。

    1. 零值切片:当一个切片类型的变量被声明但没有被显式初始化时,它的值就是一个零值切片。零值切片不会被分配内存空间,长度和容量都是零,零值切片也可以说是 nil 切片。例如:
    1. var s []string
    2. fmt.Println(s == nil) // 输出 "true"
    1. 空切片:空切片的长度和容量也都是零,但是指向了一个真实的、虽然是空的,但已经分配了内存的数组。空切片可以通过 make 函数或者字面量语法来创建。例如:
    1. s := make([]string, 0)
    2. fmt.Println(s == nil) // 输出 "false"
    1. s := []string{}
    2. fmt.Println(s == nil) // 输出 "false"

    在这两个例子中,s 都是空切片,长度和容量都是零,但是值不是 nil。

    零值切片和空切片在大多数情况下是可以互换使用的,都可以用来表示一个空的集合。但是如果需要区分一个切片是否被显式初始化过,就需要注意它们的区别了。而 encoding/json 库对两者的处理方式就是不一样的,会将零值切片编码为“null”,而将空切片编码为 “[]”。这可能会在某些情况下引发问题,例如当接口对于数组的处理期望"[]"而非"null"时。

    讲解到这里,相信大家已经知道本文题目的答案了,如果将空的切片转化为 JSON 格式后预期得到“[]”,就需要在声明切片时,使用 make 函数或者字面量语法来创建切片。看个简单的示例:

    1. package main
    2. import (
    3. "encoding/json"
    4. "fmt"
    5. )
    6. func main() {
    7. res := make([]string, 0)
    8. // 或者 res:= []string{}
    9. // 而非 var res []string
    10. b, err := json.Marshal(res)
    11. if err != nil {
    12. panic(err)
    13. }
    14. fmt.Println(string(b))
    15. }

    运行代码看下效果:

    1. $ go run main.go
    2. []

    可以看出,达到了预期的效果。

    小结

    本文讲解了零值切片(nil 切片)和空切片的定义和差异,如果想将空的切片转化为 JSON 格式后得到 “[]”而不是“null”,最好的方式是使用 make 函数或者字面量语法来创建切片。

  • 相关阅读:
    【JavaWeb】阿里的德鲁伊和c3p0
    scanf导致程序运行时出现stack smashing
    DNA修饰碳纳米管|DNA修饰单层二硫化钼|DNA修饰二硫化钨(注意事项)
    Django(一、简介,安装与使用)
    前端跨域问题的解决思路
    visual studio使用注意
    使用EXCEL制作核酸检测结果异常人员活动轨迹地图
    C到C++的敲门砖-1
    Feign调用异常触发降级捕获异常
    【leetcode34----最小差值】
  • 原文地址:https://blog.csdn.net/luduoyuan/article/details/133188023