Chromium Chronicle #24:StrongAlias、IdType 和 TokenType

第 24 集:盧卡斯安福維奇於華盛頓州貝爾維尤地區 (2021 年 8 月)
上一集

您能在以下程式碼中發現錯誤嗎?你會看到 錯誤 也就是程式碼審查機制 是否只看電話網站?

Token CreateToken(int command_data, int buffer_id);
...
auto token = CreateToken(GetCommandBufferId(), GetCommandData());

同一類型有時可能代表來自不相容網域的值。 這通常會發生在整數或字串等非特定資料類型上。 以上範例說明瞭這會如何造成錯誤。 幸好,Chromium 的 //base 可讓您輕鬆引入明確、不同的類型:

#include "base/types/strong_alias.h"

// The first template argument of StrongAlias is a "tag" type.
// The "tag" type is used to distinguish between different
// StrongAlias types.
using CommandData = base::StrongAlias<class CommandDataTag, int>;
using CommandBufferId = base::StrongAlias<class CommandBufferIdTag, int>;

Token CreateToken(CommandData command_data, CommandBufferId buffer_id);

分離類型來提高可讀性。 此外,StrongAlias 會在編譯期間擷取類型組合:

test.cc:456:16: error: no matching function for call to 'CreateToken'
  auto token = CreateToken(GetCommandBufferId(), GetCommandData());
               ^~~~~~~~~~~
test.cc:123:7: note: candidate function not viable: no known conversion from
'StrongAlias<class CommandBufferIdTag, [...]>' to
'StrongAlias<class CommandDataTag, [...]>' for 1st argument
Token CreateToken(CommandData command_data, CommandBufferId buffer_id);
      ^

編譯器會發現這些型別不相容, 因為類型。 StrongAlias 接受任何類型的「代碼」類型。 這個範例顯示,「代碼」而且無論位置為何都不需要類型定義 您可以使用不存在的類別就地宣告正常運作。

未來會取代非特定類型 (例如 bool、int、字串), 請考慮以下替代方案:

  • 請使用 base::IdType32<TagType>,而不要使用 int32_t 做為 ID。
  • 請使用 base::TokenType<TagType>,而非明確的 base::UnguessableToken
  • 使用列舉類別而非布林值 (例如,kForReloadkNotForReload,而非 truefalse)。
  • 將其他非特定類型替換為 base::StrongAlias<TagType, SomeWrappedType>