json

使用

v标准库的json模块有点特别:

  1. 基于C语言的cJSON库实现

  2. 没有使用运行时反射,性能会更好

  3. 解析JSON功能在编译器内部实现,内置支持JSON

具体如何使用json.encode()和json.decode()函数,参考内置JSON章节

实现原理

下面主要分析如何实现内置JSON的基本原理:

  1. cJSON源文件存放在编译器源代码thirdparty/cJSON目录中

  2. vlib/json/json_primitives.v对cJSON进行简单的封装

  3. 编译器进行语法解析时,如果碰到json.encode和json.decode函数,调用json_primitives包的函数进行编码和解码

  4. 解析器解析到json.encode(),会根据要解析的变量及其类型,调用cJSON的创建节点对象,构造节点函数,构造出节点数,然后调用cJSON_PrintUnformatted(),生成对应的json字符串

  5. 解析器解析到json.decode(),会根据要解析的字符串和结构模板,调用cJSON_Parse(),生成cJSON对象,然后赋值给v变量

    就是在vlib/json/json_primitives.v对两个函数进行了简单封装:

  fn json_parse(s string) &C.cJSON { //解码
  	return C.cJSON_Parse(s.str)
  }
  
  // json_string := json_print(encode_User(user)) 
  fn json_print(json &C.cJSON) string { //编码
  	s := C.cJSON_PrintUnformatted(json)
  	return tos(s, C.strlen(s))
  }

cJSON项目:https://github.com/DaveGamble/cJSON

cJSON使用参考:

cJSON结构体

链表结构实现:

解码(parse)

编码(print)

不过,按V作者的说法,后面会移除对cJSON库的依赖,自己实现。

应用举例

一般的json文件都能够顺利解码。但是,有些json文件把key和value都加了引号,解码就需要一些技巧,举例如下:

输出:

最后更新于

这有帮助吗?