如何将值映射到 Rust 中的类型?

Wal*_*ard 3 generics types traits rust

我正在编写一个程序,它在命令行上接受数字类型,然后使用该类型调用通用函数。例如,我这样运行程序:

my_programme u32
Run Code Online (Sandbox Code Playgroud)

...在我的代码中,我有:

my_programme u32
Run Code Online (Sandbox Code Playgroud)

如果我想对 8、16、32 和 64 位整数(有符号和无符号)执行此操作,则需要大量调用my_generic_function(). 它看起来凌乱,似乎没有必要。

我可以在&stror Stringvalues 和 type之间定义一个映射T,或者编写一个函数来返回 type T,而不是 match 语句,我可以只写:

match cli_type
{
   "u32" =>
   {
       my_generic_function::<u32>(args);
   },
   "u16" =>
   ...
Run Code Online (Sandbox Code Playgroud)

Pet*_*all 6

Rust 在运行时不保留任何类型信息。标准库中有一个函数std::any::type_name,它可以为您提供类型的名称,但它只是一个字符串,无法回到类型的世界。这一切都发生在编译时,以后无法更改。

但是,您可以使用宏保存一些代码:

macro_rules! make_call_typed {
   ($($t: ty),*) => {
       fn call_typed(input: &str, args: &str) {
           match input {
               $(
                   stringify!($t) => {
                       my_generic_function::<$t>(args);
                   }
               ),*
               other => panic!("unexpected type: {}", other)
           }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当你这样称呼它时:

make_call_typed!(u32, u16, i32, i16);
Run Code Online (Sandbox Code Playgroud)

它将生成如下代码:

fn call_typed(input: &str, args: &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),
    }
}
Run Code Online (Sandbox Code Playgroud)