同一种编程语言之间的数据通信非常简单,因为数据的规范都是相同的,所以输入和输出不需要做任何转换。但是在不同的编程语言之间做数据通信,就比较麻烦了。比如,一种语言按照自身的标准规范输出了一份数据,另一门语言接收到时需要按照自身编程语言标准进行对齐。
对齐一门语言的数据或许还没啥,但是如果对接的语言多了,你就需要写很多份能够与之对应的数据对齐转换代码。编写和维护的成本可想而知,那么目前有没有一种通用,而且各个编程语言都能够支持的数据格式呢?
答案是JSON。
什么是JSON
JSON,是 JavaScript Object Notation的缩写,翻译过来就是“JS对象符号”。其实JSON最初是被设计为JavaScript的一个子集,但最终因为和编程语言无关,所以成为了一种开放标准的常见数据格式。
虽然JSON是源自于JavaScript,但到目前很多编程语言都有了JSON解析的库,包括C、C 、Java、Perl、Python等等。除此之外,还有很多编程语言内置了JSON生成和解析的方法。
有了编程语言内置方法解析和生成JSON的支持,JSON成为了理想的数据交换格式。
JSON基于两种结构:
- 名字/值对集合
- 有序值列表
各种编程语言都以某种形式支持着这两种结构。比如,PHP的Array既支持名字/值对集合,又支持有序值列表;在Objective-C中,名字/值对集合就是字典,有序值列表就是数组。
名字/值对集合,在Java和JavaScript中都被称为对象。其JSON语法图如下:
如上语法图所示,对象是以左大括号开头和右大括号结尾,名字后面跟冒号,名字/值对用逗号分隔。比如:
代码语言:javascript复制{"name1":"val1","name2":"val2"}
有序值列表在JSON和JavaScript中都是叫数组,其语法图如下:
可以看到,数组是以左中括号开头,以右中括号结尾,值以逗号分隔。数组代码如下所示:
代码语言:javascript复制[[7,11,21]]
语法图中,值的语法图如下:
可以看到,值可以是字符串、数字、对象、数组、布尔值、空值。根据这个语法,JSON可以通过实现对象和数组的嵌套来描述更为复杂的数据结构。
JSON是没有注释的,水平制表符、换行符、回车符都会被当做空格。字符串由双引号括起来,里面可以使零到多个Unicode字符序列,使用反斜杠来进行转义。
综上所述,JSON是基于键值对集合以及有序值列表这两种结构的纯文本形式的数据交换格式。大白话讲就是,JSON是一段纯文本,这段纯文本是按照一定的规则组合在一起的,其中的两大主体就是字典和数组。
JSON的使用场景
JSON的数据结构和任何一门编程语言的语法结构比起来都要简单得多,但它能干的事儿却一点也不少,甚至可以完整地描述出一门编程语言的代码逻辑。比如,下面的这段JavaScript代码:
代码语言:javascript复制if (hour < 18) {
greeting = "Good day";
}
这段JS代码的逻辑是,当hour变量小于18时,greeting设置为Good day字符串,根据JavaScript的语法规则,完整逻辑的语法树结构可以通过JSON描述出来。对应的JSON如下:
代码语言:javascript复制{
"type": "Program",
"body": [
{
"type": "IfStatement",
"test": {
"type": "BinaryExpression",
"left": {
"type": "Identifier",
"name": "hour"
},
"operator": "<",
"right": {
"type": "Literal",
"value": 18,
"raw": "18"
}
},
"consequent": {
"type": "BlockStatement",
"body": [
{
"type": "ExpressionStatement",
"expression": {
"type": "AssignmentExpression",
"operator": "=",
"left": {
"type": "Identifier",
"name": "greeting"
},
"right": {
"type": "Literal",
"value": "Good day",
"raw": ""Good day""
}
}
}
]
},
"alternate": null
}
],
"sourceType": "module"
}
从上面的JSON代码可以看出,每个语法树节点都是一个JSON对象,同级节点使用的是JSON数组。
再比如下面这段JavaScript代码:
代码语言:javascript复制button.onclick = function() {
var name = realname('Tom');
if(name.length >= 5) {
show();
}
}
其语法树结构如下图所示:
JavaScript编程语言的语法书能够使用JSON来描述,其他编程语言也可以,比如Objective-C或Swift,都能够生成自己的语法树结构,转成JSON后能够在运行期被动态地识别。因此,APP的业务逻辑动态化就不仅限于使用JavaScript这一门语言来编写,而是可以选择使用其他你熟悉的语言。
JSON解析以及其效率探究
在Objective-C中,JSON解析用的是 NSJSONSerialization 类,该类可以用于JSON数据和系统对象之间的转换。
代码语言:javascript复制 (nullable NSData *)dataWithJSONObject:(id)obj options:(NSJSONWritingOptions)opt error:(NSError **)error;
(nullable id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
实际上,JSON不仅能够描述业务数据使得业务数据能够动态更新;还可以用来描述业务逻辑,以实现业务逻辑的动态化;除此之外,还可以用来描述页面布局。
试想一下,如果将JSON应用到更大的场景时,比如对编程语言的描述或者界面布局的描述,其生成的JSON文件可能会很大,因此对这种大JSON文件解析性能的要求也会更高。那么,有没有比原生的NSJSONSerialization解析性能更好的JSON解析方法呢?
2019年2月,simdjson发布,其GitHub地址如下:
代码语言:javascript复制https://github.com/lemire/simdjson
simdjson是一款快速JSON解析器,号称每秒可解析千兆字节的JSON文件。
simdjson和其他JSON解析器的对比如下所示:
可以看到,只有 simdjson 能够达到每秒千兆字节级别,并且远远高于其他JSON解析器。所以说,如果你的项目中有大JSON文件的解析需求,那么就用simdjson吧!
关于simdjson的详细信息以及相关使用,我在这里就不赘述了,大家感兴趣的话可以自行搜索。
以上。