空table编码为array还是object

最后更新于:2022-04-01 02:16:32

# 编码为array还是object 首先大家请看这段源码: ~~~ -- http://www.kyne.com.au/~mark/software/lua-cjson.php -- version: 2.1 devel local json = require("cjson") ngx.say("value --> ", json.encode({dogs={}})) ~~~ 输出结果 > value --> {"dogs":{}} 注意看下encode后key的值类型,"{}" 代表key的值是个object,"[]" 则代表key的值是个数组。对于强类型语言(c/c++, java等),这时候就有点不爽。因为类型不是他期望的要做容错。对于lua本身,是把数组和字典融合到一起了,所以他是无法区分空数组和空字典的。 参考openresty-cjson中额外贴出测试案例,我们就很容易找到思路了。 ~~~ -- 内容节选lua-cjson-2.1.0.2/tests/agentzh.t === TEST 1: empty tables as objects --- lua local cjson = require "cjson" print(cjson.encode({})) print(cjson.encode({dogs = {}})) --- out {} {"dogs":{}} === TEST 2: empty tables as arrays --- lua local cjson = require "cjson" cjson.encode_empty_table_as_object(false) print(cjson.encode({})) print(cjson.encode({dogs = {}})) --- out [] {"dogs":[]} ~~~ 综合本章节提到的各种问题,我们可以封装一个json encode的示例函数: ~~~ function json_encode( data, empty_table_as_object ) --lua的数据类型里面,array和dict是同一个东西。对应到json encode的时候,就会有不同的判断 --对于linux,我们用的是cjson库:A Lua table with only positive integer keys of type number will be encoded as a JSON array. All other tables will be encoded as a JSON object. --cjson对于空的table,就会被处理为object,也就是{} --dkjson默认对空table会处理为array,也就是[] --处理方法:对于cjson,使用encode_empty_table_as_object这个方法。文档里面没有,看源码 --对于dkjson,需要设置meta信息。local a= {};a.s = {};a.b='中文';setmetatable(a.s, { __jsontype = 'object' });ngx.say(comm.json_encode(a)) local json_value = nil if json.encode_empty_table_as_object then json.encode_empty_table_as_object(empty_table_as_object or false) -- 空的table默认为array end if require("ffi").os ~= "Windows" then json.encode_sparse_array(true) end pcall(function (data) json_value = json.encode(data) end, data) return json_value end ~~~
';