قسمت 24: توسط Łukasz Anforowicz در Bellevue, WA (اگوست 2021)
قسمت های قبلی
آیا می توانید اشکال در کد زیر را تشخیص دهید؟ آیا وقتی فقط به callsite نگاه می کنید، اشکال را در بررسی کد مشاهده می کنید؟
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، رشته)، این گزینه ها را در نظر بگیرید:
- به جای استفاده از
int32_t
به عنوان شناسه ازbase::IdType32<TagType>
استفاده کنید. -
base::TokenType<TagType>
به جایbase::UnguessableToken
استفاده کنید. - از یک کلاس enum به جای bool استفاده کنید (مثلا
kForReload
،kNotForReload
به جایtrue
،false
). -
base::StrongAlias<TagType, SomeWrappedType>
سایر انواع غیر اختصاصی را جایگزین کنید.