每周技巧 #18:使用 Substitute 进行字符串格式化
本节阅读量:本文翻译自 Abseil 官网的 Tip of the Week #18: String Formatting with Substitute。
原文最初作为 TotW #18 发布于 2012 年 10 月 4 日。
更新于 2022 年 11 月 16 日。
这种事情总会发生:你正在写代码,突然需要根据一个模板和一些运行时值组装出一个新字符串。也许这是一次失败 Stubby 调用的错误消息,也许是某个内部流程发送邮件的正文。在 google3 之外,字符串格式化最常见的机制大概是 sprintf/snprintf。但当我们在代码库中穿行时,会看到人们做过很多事情,也会看到很多地方里,C++ 工程师为了完成这个任务花了太多时间、太多周期和太多代码行。本周技巧会走过几个常见选项,并指出它们各自的缺点。
方案 1:字符串拼接(内置)
有些人仍然会直接使用基本的字符串拼接:
|
|
正如我们在 技巧 #3 中看到的,这种方法有问题:对 operator+() 的链式调用最终会创建并浪费临时对象,还会导致对数据的不必要拷贝。
方案 2:absl::StrCat()(absl/strings/str_cat.h)
就像技巧 #3 里说的,absl::StrCat() 可以避免这些拷贝,替我们处理数值转换,并且允许我们高效地操作 string_view(当调用方传入 C 风格字符串时,这一点更好):
|
|
不过,一眼看清这个字符串最终到底长什么样仍然有点困难:空格在哪里?字符串里的括号是否正确匹配?
方案 3:absl::Substitute(absl/strings/substitute.h)
不过,还有一个更好的选项:absl::Substitute()。Substitute() 使用和 StrCat() 相同的技术,让你可以传入数值、std::string、char* 和 string_view。它不要求你记住用于数值类型(或 string_view)的晦涩格式字符串。
虽然大家或多或少都能理解 printf 风格的格式字符串,但 Substitute 的格式字符串同样不容易被误读:
|
|
可读性好,性能也更好?LGTM。