C++ 使用 jsoncpp 编写代码优化,提高人类友好程度
一、背景说明
日常使用 jsoncpp创建 Json 时,经常需要先创建子 json ,对子 json 赋值完毕,然后再保存到父 json 中,这种代码结构与人类的逻辑不一致,造成编写、阅读与理解上的困难。
二、优化发现
前几天使用 cpp-httplib 时,看到代码中大量使用 lambda 回调函数 ,使代码简捷程度大幅提升。今天使用 jsonCpp 时,对于先创建对象再赋值保存非常不满,于是动手改造后,大幅提高了人类友好程度。
三、灵感创造
如果"json[‘key’]="后面可以直接编写函数返回 “Json::Value” ,那么人性化的添加顺序就可以达到,就不会再需要在添加该对象前初始化。lambda 函数可以随用随申请,写到右值位置十分合适,但是左值要求的类型并不是函数,因此可以调用一个用于返回左值类型的函数,参数填充要调用的 lambda 表达式,这样就可以两全其美了。因此构造了一个中间函数。
下面的代码中,关键部分为第二行的这个中间函数,作用为调用传入的 lambda 函数,返回左值需要的类型:
std::function<Json::Value()>runs = [&]()->Json::Value { return Json::Value(); };
auto func = [&](std::function<Json::Value()>f){ return f(); };
Json::Value val = func(runs);
注意:std::function、auto、lambda 都要求 C++11 及以上,编译时可添加 –std=c++11 参数
四、代码实践
1.要生成的 json
{
"graden": "six",
"leaders": [
"sam",
"tim"
],
"students": [
{
"name": "andy",
"sex": "boy"
},
{
"name": "alice",
"sex": "girl"
}
],
"teacher": "tom"
}
2.传统构造方法
层次不清晰,顺序不符合人类直觉,且不易在 IDE 中进行代码折叠。
void classJson(){
Json::Value jClass;
jClass["graden"] = "six";
jClass["teacher"] = "tom";
Json::Value jLeader;
jLeader.append("sam");
jLeader.append("tim");
jClass["leaders"] = jLeader;
Json::Value jStudents;
Json::Value jItem;
jItem["name"] = "andy";
jItem["sex"] = "boy";
jStudents.append(jItem);
jItem.clear();
jItem["name"] = "alice";
jItem["sex"] = "girl";
jStudents.append(jItem);
jClass["students"] = jStudents;
Json::FastWriter write;
cout << write.write(jClass) << endl;
}
3.优化后的代码
在代码折叠后依旧符合人类直觉。
void specialJson(){
std::function<Json::Value()>runs = [&]()->Json::Value { return Json::Value(); };
auto func = [&](std::function<Json::Value()>f){ return f(); };
Json::Value val = func(runs);
Json::Value jSpecial;
jSpecial["graden"] = "six";
jSpecial["teacher"] = "tom";
jSpecial["leaders"] = func([&]()->Json::Value {
Json::Value jLeaders;
jLeaders.append("sam");
jLeaders.append("tim");
return jLeaders;
});
jSpecial["students"] = func([&]()->Json::Value {
Json::Value jStudents;
jStudents.append(func([&]()->Json::Value {
Json::Value jAndy;
jAndy["name"] = "andy";
jAndy["sex" ] = "boy";
return jAndy;
}));
jStudents.append(func([&]()->Json::Value {
Json::Value jALice;
jALice["name"] = "alice";
jALice["sex"] = "girl";
return jALice;
}));
return jStudents;
});
Json::FastWriter write;
cout << write.write(jSpecial) << endl;
}
4.输出结果
{"graden":"six","leaders":["sam","tim"],"students":[{"name":"andy","sex":"boy"},{"name":"alice","sex":"girl"}],"teacher":"tom"}
{"graden":"six","leaders":["sam","tim"],"students":[{"name":"andy","sex":"boy"},{"name":"alice","sex":"girl"}],"teacher":"tom"}
5.完整代码
#include <iostream>
#include "json/json.h"
using namespace std;
void classJson(){
Json::Value jClass;
jClass["graden"] = "six";
jClass["teacher"] = "tom";
Json::Value jLeader;
jLeader.append("sam");
jLeader.append("tim");
jClass["leaders"] = jLeader;
Json::Value jStudents;
Json::Value jItem;
jItem["name"] = "andy";
jItem["sex"] = "boy";
jStudents.append(jItem);
jItem.clear();
jItem["name"] = "alice";
jItem["sex"] = "girl";
jStudents.append(jItem);
jClass["students"] = jStudents;
Json::FastWriter write;
cout << write.write(jClass) << endl;
}
void specialJson(){
std::function<Json::Value()>runs = [&]()->Json::Value { return Json::Value(); };
auto func = [&](std::function<Json::Value()>f){ return f(); };
Json::Value val = func(runs);
Json::Value jSpecial;
jSpecial["graden"] = "six";
jSpecial["teacher"] = "tom";
jSpecial["leaders"] = func([&]()->Json::Value {
Json::Value jLeaders;
jLeaders.append("sam");
jLeaders.append("tim");
return jLeaders;
});
jSpecial["students"] = func([&]()->Json::Value {
Json::Value jStudents;
jStudents.append(func([&]()->Json::Value {
Json::Value jAndy;
jAndy["name"] = "andy";
jAndy["sex" ] = "boy";
return jAndy;
}));
jStudents.append(func([&]()->Json::Value {
Json::Value jALice;
jALice["name"] = "alice";
jALice["sex"] = "girl";
return jALice;
}));
return jStudents;
});
Json::FastWriter write;
cout << write.write(jSpecial) << endl;
}
int main(int argc, const char * argv[]) {
classJson();
specialJson();
getchar();
return EXIT_SUCCESS;
}
五、优化方向
该函数应该使用模板进行构造,以便提高代码的通用性。
六、参考使用
1.cpp-httplib 2.jsoncpp
|