The Chromium Chronicle #24: StrongAlias, IdType, और TokenType

एपिसोड 24: बेलव्यू, वॉशिंगटन में लुकास ऐनफ़ोरोविच का गाना (अगस्त, 2021)
पिछले एपिसोड

क्या आपको नीचे दिए गए कोड में गड़बड़ी की जानकारी मिली है? क्या आपको सिर्फ़ कॉलसाइट देखते समय, कोड की समीक्षा में गड़बड़ी गड़बड़ी दिखती है?

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, स्ट्रिंग) के बजाय, इन विकल्पों पर विचार करें:

  • int32_t को आइडेंटिफ़ायर के तौर पर इस्तेमाल करने के बजाय, base::IdType32<TagType> का इस्तेमाल करें.
  • किसी खास base::UnguessableToken के बजाय, base::TokenType<TagType> का इस्तेमाल करें.
  • बूल के बजाय, Enum क्लास का इस्तेमाल करें (उदाहरण के लिए, true, false के बजाय kForReload, kNotForReload).
  • जो खास टाइप नहीं हैं उन्हें base::StrongAlias<TagType, SomeWrappedType> से बदलें.