.expect( format!() ): 预期为 `&str`,找到了结构体 `String`

Eva*_*oll 5 macros rust

我尝试创建一个宏来替换,

first: Some(first.as_ref().parse::<u64>().expect("Could not parse 'first'"))
Run Code Online (Sandbox Code Playgroud)

我已经在其他模块(例如Clap with )values_t!中看到了这一点,我尝试抽象这一点并没有扩展到类型。我写了这个,

first: Some(first.as_ref().parse::<u64>().expect("Could not parse 'first'"))
Run Code Online (Sandbox Code Playgroud)

这会产生以下错误,

macro_rules! parse_u64 {
  ($var:ident) => {
    Some(
      $var
      .as_ref()
      .parse::<u64>()
      .expect(  format!("Could not parse '{:?}'", stringify!($var))  )
    ) 
  };
}
Run Code Online (Sandbox Code Playgroud)

我在这里做错了什么:这是一个简单的宏,链中只有三件事?为什么会出现此错误以及如何修复它?


您可以在Rust Playground 示例中看到这一点

Frx*_*rem 12

正如您在自己的答案中提到的,expect需要 a所以您不能直接&str传递 a :String

.expect(format!("Could not parse '{:?}'", stringify!($var)).as_str())
Run Code Online (Sandbox Code Playgroud)

但是,即使没有错误,这也会执行字符串格式化(并分配新字符串),所以我建议这样做:

.unwrap_or_else(|err| panic!("Could not parse '{:?}': {}", stringify!($var), err))
Run Code Online (Sandbox Code Playgroud)

这实际上与上面的相同,unwrap_or_else只是在错误情况下调用它的闭包。


或者,在这种特定情况下,您可以在编译时将字符串文字与 串联起来concat!,这也避免了以下成本format!

.expect(concat!("Could not parse '", stringify!($var), "'"))
Run Code Online (Sandbox Code Playgroud)