The Chromium Chronicle #24: StrongAlias وIdType وTokenType

الحلقة 24: من إعداد "لوكاس أنفورويتش" في مدينة بلفو، واشنطن (آب (أغسطس) 2021)
الحلقات السابقة

هل يمكنك اكتشاف الخطأ في الرمز أدناه؟ هل سترى الخطأ في مراجعة الرمز، عند النظر إلى موقع الاتّصال فقط؟

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

وقد يمثل النوع نفسه في بعض الأحيان قيمًا من نطاقات غير متوافقة. يحدث هذا عادةً لأنواع البيانات غير المحددة مثل الأعداد الصحيحة أو السلاسل. ويوضّح المثال أعلاه كيف يمكن أن يؤدي ذلك إلى حدوث أخطاء. لحسن الحظ، يسهّل //base في Chromium تقديم أنواع واضحة ومميزة:

#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 كمعرّف.
  • يمكنك استخدام base::TokenType<TagType> بدلاً من قيمة base::UnguessableToken غير محدّدة.
  • استخدم فئة تعداد بدلاً من قيمة منطقية (على سبيل المثال، kForReload، kNotForReload بدلاً من true، false).
  • استبدِل الأنواع الأخرى غير المحدّدة بـ base::StrongAlias<TagType, SomeWrappedType>.