go语言解析带注释的json

一、背景和意义

标准的json格式是不带注释,但是有时候为了方便理解json中各字段的含义,需要支持带注释的json。例如在日常工作中常用的接口文档管理平台yapi在配置接口参数与接口返回、或者创建mock数据时,就支持配置带注释的json。本文给出用go语言解析带注释的json的示例。

二、go语言解析普通json

go语言官方自带的json库可以解析普通的json。例如,我们创建一个main.go文件,代码如下:

go 复制代码
package main

import (
   "encoding/json"
   "fmt"
)

type user struct {
   Name    string
   Age     int
   Address struct {
      City    string
      Country string
   }
}

func main() {
   jsonStr := `{
        "name": "ZhangSan",
        "age": 11,
        "address": {
          "city": "Shanghai",
          "country": "China"
        }
      }`
   user := &user{}
   err := json.Unmarshal([]byte(jsonStr), user)
   if err != nil {
      fmt.Printf("json解析失败:%+v", err)
   } else {
      fmt.Printf("json解析结果:%+v", user)
   }
}

运行go run main.go命令,运行结果为:

log 复制代码
json解析结果:&{Name:ZhangSan Age:11 Address:{City:Shanghai Country:China}}

但是假如我们在json中增加以// ... 或者/* ... */格式的注释:

go 复制代码
package main

import (
   "encoding/json"
   "fmt"
)

type user struct {
   Name    string
   Age     int
   Address struct {
      City    string
      Country string
   }
}

func main() {
   jsonStr := `{
        "name": "ZhangSan",    // 姓名
        "age": 11,             // 年龄
        /* 地址信息 开始 */
        "address": {
          "city": "Shanghai",
          "country": "China"
        }
        /* 地址信息 结束 */
      }`
   user := &user{}
   err := json.Unmarshal([]byte(jsonStr), user)
   if err != nil {
      fmt.Printf("json解析失败:%+v", err)
   } else {
      fmt.Printf("json解析结果:%+v", user)
   }
}

然后执行命令go run main.go,可看到运行结果为:

log 复制代码
json解析失败:invalid character '/' looking for beginning of object key string

三、go语言解析带注释json

使用github.com/titanous/json5库可以解析带注释的json

go 复制代码
package main

import (
   "fmt"
   "github.com/titanous/json5"
)

type user struct {
   Name     string
   Age      int
   HomePage string
   Address  struct {
      City    string
      Country string
   }
}

func main() {
   jsonStr := `{
        "name": "ZhangSan",    // 姓名
        "age": 11,             // 年龄
        /* 地址信息 开始 */
        "address": {
          "city": "Shanghai",
          "country": "China"
        }
        /* 地址信息 结束 */
      }`
   user := &user{}
   err := json5.Unmarshal([]byte(jsonStr), user)
   if err != nil {
      fmt.Printf("json解析失败:%+v", err)
   } else {
      fmt.Printf("json解析结果:%+v", user)
   }
}

运行结果如下:

log 复制代码
json解析结果:&{Name:ZhangSan Age:11 HomePage: Address:{City:Shanghai Country:China}}

四、其他特殊情况验证

按理来说,按理来说,// .../* ... */如果是出现在字符串中,那么他们不应该为注释处理,我们验证一下github.com/titanous/json5是否能够正确如果这种情况,将main.go文件修改为:

go 复制代码
package main

import (
   "fmt"
   "github.com/titanous/json5"
)

type user struct {
   Name     string
   Age      int
   HomePage string
   Comment  string
   Address  struct {
      City    string
      Country string
   }
}

func main() {
   jsonStr := `{
        "name": "ZhangSan",    // 姓名
        "age": 11,             // 年龄

        /* homePage字段的值中有"//",但它不应该被作为注释处理 */
        "homePage": "https://www.testpage.com/index.html",
        "comment": "此处测试一下,/* 这里的注释是否能够正确解析 */",

        /* 地址信息 开始 */
        "address": {
          "city": "Shanghai",
          "country": "China"
        }
        /* 地址信息 结束 */
      }`
   user := &user{}
   err := json5.Unmarshal([]byte(jsonStr), user)
   if err != nil {
      fmt.Printf("json解析失败:%+v", err)
   } else {
      fmt.Printf("json解析结果:%+v", user)
   }
}

运行结果为:

log 复制代码
json解析结果:&{Name:ZhangSan Age:11 HomePage:https://www.testpage.com/index.html Comment:此处测试一下,/* 这里的注释是 否能够正确解析 */ Address:{City:Shanghai Country:China}}

可以看到,github.com/titanous/json5对于这种特殊情况的处理也是完全正确的。

相关推荐
朱容zr33313310 分钟前
为什么推荐使用自增主键?使用UUID作为主键的优缺点是什么?
java·运维·数据库·后端·mysql·面试·性能优化
名字还没想好☜19 分钟前
Go 表驱动测试实战:用 t.Run 子测试组织可维护的单元测试
golang·单元测试·log4j·go·testing
用户6081865279020 分钟前
一文吃透 Avalonia 布局容器|Grid 到 UniformGrid 核心用法 + 语法糖实战
后端
Ai拆代码的曹操35 分钟前
Dubbo 线程池爆满排坑:Linux 用户线程数限制,一个容易被忽略的根因
后端·源码阅读
不吃辣49044 分钟前
vibe coding | 如何做一个 AI 音乐生成工具?
java·人工智能·后端·ai·ai编程
坏心思1 小时前
布隆过滤器太难删除?深入理解布谷鸟过滤器:原理、源码、性能对比与工程选型
后端
城管不管1 小时前
重生——第五次面试2026.8.1一面
java·数据库·后端·ai·面试·职场和发展·agent
SkyStream1 小时前
无人机系列-篇三-AI视频识别接入架构与优化
后端
SkyStream1 小时前
无人机系列-篇二-ZLMediaKit多路流管理与分发
后端
geovindu2 小时前
java: Gale-Shapley Algorithm
java·开发语言·后端·算法