#rust #type-conversion
Вопрос:
Я пишу программу, которая принимает числовой тип в командной строке, а затем вызывает универсальную функцию, использующую этот тип. Например, я запускаю программу таким образом:
my_programme u32
…и в моем коде у меня есть:
match cli_type
{
"u32" =>
{
my_generic_function::<u32>(args);
},
"u16" =>
...
Если я хочу сделать это для 8, 16, 32 и 64-разрядных целых чисел, как со знаком, так и без знака, это много вызовов my_generic_function()
. Это выглядит грязно и кажется ненужным.
Могу ли я определить сопоставление между amp;str
String
значениями или и типом T
или написать функцию , возвращающую тип T
, чтобы вместо оператора соответствия я мог просто написать:
my_generic_function::<get_type(cli_type)>(args);
Ответ №1:
Rust не хранит никакой информации о типе во время выполнения. В стандартной библиотеке есть функция std::any::type_name
, которая может дать вам имя типа , но это всего лишь строка, и нет никакого способа вернуться в мир типов. Все это происходит во время компиляции и не может быть изменено позже.
Однако вы можете сохранить некоторый код с помощью макроса:
macro_rules! make_call_typed {
($($t: ty),*) => {
fn call_typed(input: amp;str, args: amp;str) {
match input {
$(
stringify!($t) => {
my_generic_function::<$t>(args);
}
),*
other => panic!("unexpected type: {}", other)
}
}
}
}
Когда ты называешь это так:
make_call_typed!(u32, u16, i32, i16);
Он будет генерировать код, подобный этому:
fn call_typed(input: amp;str, args: amp;str) {
match input {
"u32" => {
my_generic_function::<u32>(args);
}
"u16" => {
my_generic_function::<u16>(args);
}
"i32" => {
my_generic_function::<i32>(args);
}
"i16" => {
my_generic_function::<i16>(args);
}
other => panic!("unexpected type: {}", other),
}
}