24. bölüm: Łukasz Anforowicz, Bellevue, Washington'da (Ağustos 2021)
Önceki bölümler
Aşağıdaki kodda hatayı tespit edebiliyor musunuz? Bir kod incelemesinde hatayı yalnızca çağrı sitesine bakarken görür müydünüz?
Token CreateToken(int command_data, int buffer_id);
...
auto token = CreateToken(GetCommandBufferId(), GetCommandData());
Aynı tür, bazen uyumsuz alanlardan gelen değerleri temsil edebilir.
Bu durum genellikle tamsayılar veya dizeler gibi belirli olmayan veri türleri için geçerlidir.
Yukarıdaki örnekte, bu durumun nasıl hatalara neden olabileceği gösterilmektedir.
Neyse ki Chromium'un //base
özelliği, uygunsuz ve farklı türleri tanıtmayı kolaylaştırıyor:
#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);
Ayrı türler okunabilirliği artırır.
Ayrıca StrongAlias
, derleme sırasında tür karmalarını yakalar:
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);
^
Derleyici, farklı bir "etiket" türüne sahip oldukları için türlerin uyumsuz olduğunu görür.
StrongAlias
, "etiket" türü olarak her türü kabul eder.
Örnek, "tag" türünün hiçbir yerde tür tanımına bile gerek olmadığını göstermektedir. Mevcut olmayan bir sınıfın yerinde ileriye dönük bildirimi sorunsuz bir şekilde çalışmaktadır.
Gelecekte, spesifik olmayan bir tür (ör. bir Bool, bir int, bir dize) yerine, aşağıdaki alternatifleri değerlendirin:
- Tanımlayıcı olarak
int32_t
kullanmak yerinebase::IdType32<TagType>
kullanın. - Spesifik olmayan bir
base::UnguessableToken
yerinebase::TokenType<TagType>
kullanın. - Bool yerine bir enum sınıfı kullanın (örneğin,
true
,false
yerinekForReload
,kNotForReload
). - Spesifik olmayan diğer türleri
base::StrongAlias<TagType, SomeWrappedType>
ile değiştir.