AnSwErYWJ's Blog

记一次踩坑|空table应该编码为数组还是对象

字数统计: 389阅读时长: 8 min
2017/06/16

Json有两种比较常用的数据类型:被{}包裹的对象(object),被[]包裹的数组(array

问题描述

从第三方API返回的json数据,存在一个key的值为空数组,可是经过decodeencode这两步操作后,这个key的值就变为空对象了:

1
2
3
4
5
6
7
local cjson = require('cjson')

local raw = {}
raw.name = 'answer'
raw.list = {}
local str = cjson.encode(raw)
print('after cjson encode:', str)

输出:

1
after cjson encode:	{"name":"answer","list":{}}

cjson对于空的table,会默认处理为object,对于Lua本身,是无法区分空数组和空字典的(数组和字典融合到一起了),但是对于强类型语言(C/C++, Java等),这时候就会出现问题,必须作容错处理

解决方法

使用encode_empty_table_as_object方法

1
2
3
4
5
6
7
8
local cjson = require('cjson')

local raw = {}
raw.name = 'answer'
raw.list = {}
cjson.encode_empty_table_as_object(false)
local str = cjson.encode(raw)
print('after cjson encode:', str)

输出:

1
after cjson encode:	{"name":"answer","list":[]}

更换dkjson

1
2
3
4
5
6
7
local dkjson = require('dkjson')

local raw = {}
raw.name = 'answer'
raw.list = {}
local str = dkjson.encode(raw)
print('after cjson encode:', str)

输出:

1
after cjson encode:	{"name":"answer","list":[]}

使用metatabletable标记为array

1
2
3
4
5
6
7
8
local cjson = require('cjson')

local raw = {}
raw.name = 'answer'
raw.list = {}
setmetatable(raw.list, cjson.empty_array_mt)
local str = cjson.encode(raw)
print('after cjson encode:', str)

输出:

1
after cjson encode:	{"name":"answer","list":[]}

Reference

原文作者:AnSwErYWJ

原文链接:https://answerywj.com/2017/06/16/table-encode-as-array-or-object/

发表日期:2017/06/16 15:06

版权声明:本文采用Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License进行许可.
Creative Commons License

CATALOG
  1. 1. 问题描述
  2. 2. 解决方法
    1. 2.1. 使用encode_empty_table_as_object方法
    2. 2.2. 更换dkjson库
    3. 2.3. 使用metatable将table标记为array
  3. 3. Reference