news 2026/9/8 16:42:54

nlohmann::json 的 is_null() 用法解析:如何判断 JSON 值是否为 null

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
nlohmann::json 的 is_null() 用法解析:如何判断 JSON 值是否为 null

nlohmann::json 的 is_null() 用法解析:如何判断 JSON 值是否为 null

【免费下载链接】jsonJSON for Modern C++项目地址: https://gitcode.com/GitHub_Trending/js/json

is_null()是 JSON for Modern C++(nlohmann::json)提供的便捷类型检查成员函数之一,用于判断当前 JSON 值是否恰好为null。它在解析可选字段、校验配置文件缺失项、以及遍历异构 JSON 容器等场景中高频使用。读完本文你将掌握is_null()的签名、返回值、异常保证与复杂度特性,并通过源码与测试理解它与value_t类型系统、其他is_*()函数及is_primitive()/is_structured()分类函数之间的关系。

函数签名与基本语义

nlohmann::json中,is_null()的完整声明如下:

constexpr bool is_null() const noexcept;

该函数在且仅在当前 JSON 值为#!json null时返回#!cpp true。它隶属于 basic_json 的“便捷类型检查器”(convenience type checker)一族,同族还包括 is_boolean()、is_array()、is_object()、is_string()、is_number() 等。

返回值

当前值类型is_null()返回值
#!json nulltrue
其他任意类型(boolean / number / object / array / string / binary 等)false

异常安全与复杂度

  • 异常安全noexcept保证(No-throw guarantee),该成员函数在任何情况下都不会抛出异常,因此可以放心地用于不允许抛出异常的代码路径(例如noexcept函数内部或析构函数中)。
  • 复杂度:常数时间(Constant)。整个调用只是一次类型标记的比较,不涉及遍历、分配内存或解析等操作。

从源码看实现原理

is_null()的实现极简,核心是对内部类型标记做一次相等比较。该实现位于 include/nlohmann/json.hpp#L1379-L1384:

/// @brief return whether value is null /// @sa https://json.nlohmann.me/api/basic_json/is_null/ constexpr bool is_null() const noexcept { return m_data.m_type == value_t::null; }

其中m_data.m_type是对象内部保存的“当前值类型”标记,其取值来自枚举detail::value_t。该枚举在 include/nlohmann/detail/value_t.hpp#L53-L65 中定义,覆盖了 JSON 的全部十种内部状态:

enum class value_t : std::uint8_t { null, ///< null value object, ///< object (unordered set of name/value pairs) array, ///< array (ordered collection of values) string, ///< string value boolean, ///< boolean value number_integer, ///< number value (signed integer) number_unsigned, ///< number value (unsigned integer) number_float, ///< number value (floating-point) binary, ///< binary array (ordered collection of bytes) discarded ///< discarded by the parser callback function };

注意两个易混淆的边界情况:

  1. value_t::discarded不等于value_t::nulldiscarded仅由解析回调(parser callback)在处理被丢弃的键/值时临时使用,因此一个被标记为discarded的值is_null()也会返回false
  2. nullptr字面量与 C++NULLjson(nullptr)构造出的值类型为value_t::null(下文测试用例即用json const j(nullptr)构造空值);但传入 C 风格空指针常量时必须写nullptr,直接写整数0会被当作数字处理而不会得到null值。

由于is_null()声明为constexpr,在编译期可求值的上下文中(例如静态断言或模板元编程)同样可以使用。

它在类型分类体系中的位置

从 include/nlohmann/json.hpp 中相邻的实现可以看出,is_null()不是孤立存在的,它是整套类型分类体系的基础构件:

constexpr bool is_primitive() const noexcept { return is_null() || is_string() || is_boolean() || is_number() || is_binary(); } constexpr bool is_structured() const noexcept { return is_array() || is_object(); }

也就是说:

  • is_primitive()(判断是否为原始类型)会把is_null()的结果作为其真值条件之一:null与字符串、布尔、数字、二进制一起被归为“原始(primitive)”类型,返回true
  • is_structured()(判断是否为结构化类型)与is_null()完全互补地覆盖数组与对象;
  • is_number()则由is_number_integer() || is_number_float()组合而成,其中整数分支还要进一步区分number_integernumber_unsigned

相关实现可分别在 include/nlohmann/json.hpp#L1365-L1370(is_primitive)与 include/nlohmann/json.hpp#L1372-L1377(is_structured)中查看。

完整示例:对全部 JSON 类型逐一调用 is_null()

仓库在 docs/mkdocs/docs/examples/is_null.cpp 中提供了一个覆盖所有 JSON 类型的完整示例。该示例创建了包括null、布尔、有符号/无符号整数、浮点数、对象、数组、字符串、二进制在内的九种值,并逐一调用is_null()

#include <iostream> #include <nlohmann/json.hpp> using json = nlohmann::json; int main() { // create JSON values json j_null; json j_boolean = true; json j_number_integer = 17; json j_number_unsigned_integer = 12345678987654321u; json j_number_float = 23.42; json j_object = {{"one", 1}, {"two", 2}}; json j_array = {1, 2, 4, 8, 16}; json j_string = "Hello, world"; json j_binary = json::binary({1, 2, 3}); // call is_null() std::cout << std::boolalpha; std::cout << j_null.is_null() << '\n'; std::cout << j_boolean.is_null() << '\n'; std::cout << j_number_integer.is_null() << '\n'; std::cout << j_number_unsigned_integer.is_null() << '\n'; std::cout << j_number_float.is_null() << '\n'; std::cout << j_object.is_null() << '\n'; std::cout << j_array.is_null() << '\n'; std::cout << j_string.is_null() << '\n'; std::cout << j_binary.is_null() << '\n'; }

运行输出(与 docs/mkdocs/docs/examples/is_null.output 一致):

true false false false false false false false false

两个值得注意的细节:

  1. 默认构造json j_null;得到的正是null值(这也是basic_json默认构造函数的语义),因此它是示例中唯一返回true的对象;
  2. 代码在输出前启用了std::boolalpha,让布尔结果以true/false而非1/0打印,便于阅读。

单元测试中的验证

类型检查逻辑在测试套件 tests/src/unit-inspection.cpp 的"convenience type checker"一节中得到了系统验证。其测试手法是:为每个 JSON 类型构造一个值,然后用一组CHECK断言逐一确认所有is_*()函数的行为互斥且完备。

null小节为例(tests/src/unit-inspection.cpp#L58-L74):

SECTION("null") { json const j(nullptr); CHECK(j.is_null()); CHECK(!j.is_boolean()); CHECK(!j.is_number()); CHECK(!j.is_number_integer()); CHECK(!j.is_number_unsigned()); CHECK(!j.is_number_float()); CHECK(!j.is_binary()); CHECK(!j.is_object()); CHECK(!j.is_array()); CHECK(!j.is_string()); CHECK(!j.is_discarded()); CHECK(j.is_primitive()); CHECK(!j.is_structured()); }

这里用json const j(nullptr)显式构造空值,随后验证:is_null()true、其余所有类型判定为false、同时is_primitive()trueis_structured()false。对象、数组、布尔等分节的测试(如!j.is_null())则从反方向确认了该判定的排他性。这组测试既是is_null()行为的权威依据,也可以作为读者在自己代码中安全组合各is_*()判定的参考模板。

典型使用场景

结合上述语义,is_null()在真实项目中通常用于以下场合:

  • 解析可选字段:当 JSON 对象中某键可能缺失也可能显式为null时,先用contains()find()判断键是否存在,再用at(key).is_null()区分“无此键”与“键值为 null”,从而决定是否使用默认值;
  • 遍历前的安全守卫:对来自第三方接口的嵌套 JSON,在向下取值前先用is_null()拦截空值,避免对null继续调用get<T>()或下标访问而抛出类型转换/越界异常;
  • type()配合的精确分支:如果只需要“是否是 null”一个布尔结论,直接使用is_null()即可;若需要穷举所有类型做多路分发,则可以基于 type() 返回的value_t编写switch语句。

需要提醒的是:is_null()只回答“当前值是不是null”这一事实问题,并不会替你决定“null应该当作空值处理还是当作默认值处理”——这层业务逻辑需要调用方在is_null()返回true的分支中自行实现。

版本历史

  • 自版本1.0.0起提供(since version 1.0.0),属于basic_json长久以来保持稳定的核心类型检查接口之一;其底层实现所依赖的value_t枚举同样自 1.0.0 存在。

小结

is_null()是 nlohmann::json 中成本最低、最安全的类型检查接口:常数时间复杂度、noexcept无异常保证、可constexpr求值。它的本质是对内部value_t类型标记的一次相等比较,并与is_primitive()is_structured()等高层分类函数协同工作。无论是解析可能缺失的 JSON 字段,还是编写遍历异构数据的健壮代码,将is_null()与其他is_*()函数配合使用,都是判断 JSON 值类型最直接、最不易出错的方案。

【免费下载链接】jsonJSON for Modern C++项目地址: https://gitcode.com/GitHub_Trending/js/json

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/8 16:41:58

用Markdown和字段规范,给《哈利·波特》建一座可检索的知识档案库

先说清楚&#xff0c;harrypotter09-2不是某个哈利波特游戏的破解补丁&#xff0c;也不是资源站神秘代号。这是我个人内容整理项目的命名——第 09 号专题的第二版迭代&#xff0c;主题只有一个&#xff1a;把《哈利波特》魔法世界里散落的人物、咒语、生物、事件和魔法物品&am…

作者头像 李华
网站建设 2026/9/8 16:40:55

智能温控仪表AI208X全解析:选型、PID整定与通讯实战

1. 为什么一台温控仪表还要认真选型&#xff1a;先说清楚AI208X的定位做自动化设备这行的朋友应该都有体会&#xff0c;温控仪表这东西&#xff0c;看着不起眼&#xff0c;机箱里一个35mm导轨位或者面板开孔就能装下&#xff0c;但它直接决定了产品的加热品质、设备稳定性&…

作者头像 李华
网站建设 2026/9/8 16:40:05

从部署到日常运维:KES-Operator让数据库集群管理更简单

&#x1f525;承渊政道&#xff1a;个人主页 ❄️个人专栏: 《C语言基础语法知识》 《数据结构与算法》 《C知识内容》 《Linux系统知识》 《算法刷题指南》 《测评文章活动推广》 《大模型语言路线学习》 《MySQL数据库学习》 《Python知识内容》 《cpolar知识学习》 ✨逆境不…

作者头像 李华
网站建设 2026/9/8 16:39:47

AUV建模与仿真全流程解析:从六自由度动力学到工程调试实战

简介&#xff1a;基于 MATLAB 平台的 AUV 自主水下航行器建模与仿真练习包&#xff0c;面向自动化、计算机、电子信息工程、数学等专业学生及科研入门者。压缩包内共 9 个文件&#xff0c;包含 4 个源码脚本、2 张结果静态图、1 个动态演示图像文件&#xff0c;以及 1 份说明文…

作者头像 李华