Episode 24: oleh bolasz Anforowicz di Bellevue, WA (Agustus, 2021)
Episode sebelumnya
Dapatkah Anda melihat bug pada kode di bawah? Apakah Anda akan melihat yang bug dalam tinjauan kode, ketika melihat hanya {i>callsite<i}?
Token CreateToken(int command_data, int buffer_id);
...
auto token = CreateToken(GetCommandBufferId(), GetCommandData());
Jenis yang sama terkadang dapat mewakili nilai dari domain yang tidak kompatibel.
Hal ini biasanya terjadi untuk jenis data non-spesifik seperti bilangan bulat atau string.
Contoh di atas menggambarkan bagaimana hal ini dapat menyebabkan bug.
Untungnya, //base
Chromium memudahkan Anda memperkenalkan jenis yang eksplisit dan berbeda:
#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);
Jenis terpisah meningkatkan keterbacaan.
Selain itu, StrongAlias
menangkap campuran jenis pada waktu kompilasi:
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);
^
Kompilator melihat bahwa
jenis-jenis tersebut tidak kompatibel,
karena memiliki "tag" yang berbeda .
StrongAlias
menerima jenis apa pun sebagai "tag" .
Contoh ini menunjukkan bahwa "tag" bahkan tidak memerlukan definisi
tipe di mana pun—sebuah
deklarasi maju yang diterapkan dari class yang tidak ada dapat berfungsi dengan baik.
Di masa mendatang, alih-alih jenis non-spesifik (misalnya, bool, int, string), pertimbangkan alternatif berikut:
- Gunakan
base::IdType32<TagType>
, bukanint32_t
sebagai ID. - Gunakan
base::TokenType<TagType>
, bukanbase::UnguessableToken
yang tidak spesifik. - Menggunakan class enum, bukan bool
(misalnya,
kForReload
,kNotForReload
, bukantrue
,false
). - Ganti jenis non-spesifik lainnya dengan
base::StrongAlias<TagType, SomeWrappedType>
.