ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Google C++每周贴士 #171: 别用哨兵值

2021-07-13 12:59:57  阅读:544  来源: 互联网

标签:Google 调用者 C++ 哨兵 AccountBalance 贴士 absl balance optional


(原文链接:https://abseil.io/tips/171 译者:clangpp@gmail.com)

每周贴士 #171: 别用哨兵值

哨兵值是指在特定上下文下有特别含义的值。例如,考虑如下API:

// 返回账户余额,如果账户已关闭则返回-5。
int AccountBalance();

除了-5,每个int的值都可以是AccountBalance的合法返回值。直觉上这有点奇怪:调用者是应该特殊地比较-5,还是说任何负值都能可靠地表示“账户关闭”?要是有一天系统支持余额为负了,API需要调整成为可以返回负值,不就麻爪儿了吗?

使用哨兵值增加了调用端代码的复杂性。如果碰上严谨的调用者,它就会显式地检查哨兵值:

int balance = AccountBalance();
if (balance == -5) {
  std::cerr << "account closed";
  return;
}
// 在这里使用`balance`

相比之下,有些调用者可能会检查更宽泛的数值:

int balance = AccountBalance();
if (balance <= 0) {
  std::cerr << "where is my account?";
  return;
}
// 在这里使用`balance`

而有些调用者会直接忽略哨兵值,假设它在实际中根本不会出现。

int balance = AccountBalance();
// 在这里使用`balance`

哨兵值的问题

上面的例子阐明了使用哨兵值的一些常见问题。其他问题还有:

  • 不同的系统可能使用不同的哨兵值,例如单个负值,所有负值,无限值,或随便挑的值。沟通特殊值的唯一方式就是文档。
  • 哨兵值仍然是对应类型的合法值,所以类型系统对于调用者和被调用者都不会通告数值可能不合法。如果代码和注释不一致,通常两者都是错的(译者注:指API设计得不好)。
  • 哨兵值限制了接口的演进,因为特定的哨兵值有一天也许会成为系统的合法值。
  • 一个系统的哨兵值是另一个系统的合法值,增加了多系统交互时的认知负担。

忘记检查特定的哨兵值是一个常见漏洞(bug)。在最好的情况下,使用了未经检查的哨兵值会直接在运行时使系统崩溃。更常见的是,未经检查的哨兵值可能会继续在系统里流转,一路产生错误的结果。

改为使用absl::optional

使用absl::optional而不是特殊值来指示不可用或非法的信息。

// 返回账户余额,如果账户已关闭则返回absl::nullopt
absl::optional<int> AccountBalance();

现在我们新版本AccountBalance()的调用者必须显示地在返回值中检索可能的余额,并在过程中通报结果可能不合法的情况。除非有额外的文档说明,否则调用者可以假设任何合法的int值都可以被该函数返回,而不用排除特定的哨兵值。这个简化清晰地表明了调用端代码的意图。

absl::optional<int> balance = AccountBalance();

if (!balance.has_value()) {
  std::cerr << "Account doesn't exist";
  return;
}
// 在这里使用`balance`

下次你在系统中有使用哨兵值的冲动的时候,强烈建议考虑改用适当的absl::optional

参见

  • 更多关于使用absl::optional传递参数的信息,参见每周贴士 #163
  • 关于如何决定什么时候该使用absl::optional而不是std::unique_ptr,参见TotW #123

标签:Google,调用者,C++,哨兵,AccountBalance,贴士,absl,balance,optional
来源: https://blog.csdn.net/clangpp/article/details/118696975

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有