 详解:如何判断 JSON Pointer 是否指向根文档)
nlohmann::json_pointer::empty() 详解如何判断 JSON Pointer 是否指向根文档【免费下载链接】jsonJSON for Modern C项目地址: https://gitcode.com/GitHub_Trending/js/json本文是 JSON for Modern Cnlohmann/json仓库版本 3.12.0API 指南的一部分围绕 [json_pointer::empty()] 展开它用于判断一个 JSON Pointer 是否为空、即是否指向整篇 JSON 文档的根。读完本文你将掌握该接口的签名语义、底层实现原理基于reference_tokens判空、异常与复杂度保证并通过官方示例与单元测试看到它在operator[]、parent_pointer()、pop_back()等日常操作中的典型配合用法。JSON Pointer 与“根文档”的含义JSON PointerRFC 6901是一种用字符串定位 JSON 文档内特定值的标准语法。一个 JSON Pointer 由一串以/分隔的reference token引用标记组成例如/foo/0表示“根对象的foo键取其数组的第 0 个元素”。而空字符串是合法的 JSON Pointer它表示零个引用标记即指向整篇文档根文档本身。在这个仓库中JSON Pointer 由模板类json_pointer实现class 定义在 include/nlohmann/detail/json_pointer.hpp单头文件版本为 single_include/nlohmann/json.hpp。empty()正是回答“这个指针是否指向根文档”的成员函数。函数签名与语义官方 API 文档 docs/mkdocs/docs/api/json_pointer/empty.md 给出的签名如下bool empty() const noexcept;三个关键语义要点功能返回该指针是否指向根文档即其内部是否不含任何引用标记。返回值true当且仅当该 JSON Pointer 指向根文档否则返回false。声明位置它是json_pointer的const成员函数可在常量对象上调用且不影响对象状态。异常安全与复杂度保证依据文档声明异常安全No-throw guarantee该函数在任何情况下都不会抛出异常。时间复杂度常数时间Constant。这两点由实现方式直接保证——见下一节源码剖析它只对成员向量调用std::vector::empty()既不遍历元素也不分配内存因此既无复杂度开销也无抛异常路径。源码实现剖析在 include/nlohmann/detail/json_pointer.hpp 中empty()的实现极为简洁/// brief return whether pointer points to the root document bool empty() const noexcept { return reference_tokens.empty(); }也就是说判断的依据是私有成员reference_tokens类型为std::vectorstring_t存储解析后的各个引用标记是否为空。理解这点后“指向根文档”就等价于“引用标记序列长度为 0”。reference_tokens是在构造json_pointer时由静态函数split()填充的构造函数见 include/nlohmann/detail/json_pointer.hpp。在 include/nlohmann/detail/json_pointer.hpp 中split()对空输入做了特殊处理// special case: empty reference string - no reference tokens if (reference_string.empty()) { return result; }这意味着json_pointer()或默认构造的json_pointer不产生任何引用标记因此empty()返回true而任何非空字符串如果首字符不是/split()会抛出parse_error.107“JSON pointer must be empty or begin with /”。所以从构造到判空语义是完全自洽的只有空字符串形式的指针才可能为空并指向根文档。同时可以推断由于empty()只读取reference_tokens的大小而不访问任何元素即便对指针调用也绝对安全不会触发out_of_range。完整运行示例仓库在 docs/mkdocs/docs/examples/json_pointer__empty.cpp 提供了官方示例它构造了四种指针并打印各自empty()的结果#include iostream #include nlohmann/json.hpp using json nlohmann::json; int main() { // different JSON Pointers json::json_pointer ptr0; json::json_pointer ptr1(); json::json_pointer ptr2(/foo); json::json_pointer ptr3(/foo/0); // call empty() std::cout std::boolalpha \ ptr0 \: ptr0.empty() \n \ ptr1 \: ptr1.empty() \n \ ptr2 \: ptr2.empty() \n \ ptr3 \: ptr3.empty() std::endl; }编译该文件时需确保nlohmann/json.hpp头文件可被找到可指向 single_include/nlohmann/json.hpp例如c -stdc11 -I single_include json_pointer__empty.cpp -o json_pointer__empty程序的输出见 docs/mkdocs/docs/examples/json_pointer__empty.output: true : true /foo: false /foo/0: false从输出可以得到非常直观的结论JSON Pointer含义empty()默认构造等同根文档true根文档true/foo根文档的foo字段false/foo/0foo数组的第 0 个元素false注意默认构造的json_pointerptr0与显式传空串构造的ptr1打印出来都是empty()也都为true——这印证了构造函数默认参数explicit json_pointer(const string_t s )见 include/nlohmann/detail/json_pointer.hpp使得二者等价。实战场景empty() 在元素访问与指针运算中的角色仅判断“是否指向根”看似简单但它在指针运算中起着关键的门卫作用。仓库的单元测试 tests/src/unit-json_pointer.cpp 展示了empty()最典型的实战配合1. 空指针直接索引整篇文档auto ptr _json_pointer; CHECK(ptr.empty()); CHECK(j[ptr] j); // j[]_json_pointer 等价于访问根对象 j 本身当指针为空时basic_json的operator[]接受json_pointer的重载解析到的是根文档自身这与 RFC 6901 中空指针代表整个文档的规定一致。2. 与 push_back / pop_back 的往返ptr.push_back(pi); CHECK(!ptr.empty()); // 追加引用标记后不再为空 CHECK(j[ptr] j[pi]); ptr.pop_back(); CHECK(ptr.empty()); // 弹回后恢复为空 CHECK(j[ptr] j);3. parent_pointer 与边界保护empty()还被json_pointer内部其它成员广泛依赖。例如parent_pointer()include/nlohmann/detail/json_pointer.hpp首先判断if (empty()) { return *this; // 根指针的父指针就是它自己 }而pop_back()、back()、pop_front()、front()、top()等操作则反其道而行之——当empty()为真时它们会抛出out_of_range.405错误信息 “JSON pointer has no parent”见 tests/src/unit-json_pointer.cppCHECK_THROWS_WITH_AS(ptr.pop_back(), [json.exception.out_of_range.405] JSON pointer has no parent, json::out_of_range);因此在实际业务代码中遍历、裁剪指针前先调用empty()判断是否已到达根节点是避免在空指针上执行pop_back()/front()等操作从而触发 405 异常的有效手段。版本历史empty()自3.6.0版本起加入版本 3.6.0 于 2019-03-19 发布见 ChangeLog.md 中 v3.6.0 一节当前仓库的 include/nlohmann/detail/json_pointer.hpp 头部标明版本为 3.12.0接口保持向后兼容。使用C11及以上标准即可通过单头文件nlohmann/json.hpp获得该能力。小结json_pointer::empty()以常数时间、无异常的方式告知调用者“当前 JSON Pointer 是否为空串形式、即是否指向根文档”。其实现只是一次reference_tokens向量的判空include/nlohmann/detail/json_pointer.hpp源码简单可靠。在实际应用中它是安全实现指针裁剪、父指针求值以及“空指针 整个根文档”这一 RFC 6901 语义的基石官方示例示例源码 与 输出和单元测试tests/src/unit-json_pointer.cpp都为此提供了直接可验证的依据。【免费下载链接】jsonJSON for Modern C项目地址: https://gitcode.com/GitHub_Trending/js/json创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考