.expect( format!() ): 期望`&str`,找到struct `String`

.expect( format!() ): expected `&str`, found struct `String`

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

first: Some(first.as_ref().parse::<u64>().expect("Could not parse 'first'"))

我已经在 Clap with values_t! 等其他模块中看到过这样做,我尝试对此进行抽象并没有扩展到类型。这是我写的,

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

这会产生以下错误,

first: parse_u64!(first),
       ^^^^^^^^^^^^^^^^^ expected `&str`, found struct `String`

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


你可以在这个Rust Playground example

中看到

我遇到的问题是

.expect(  format!("Could not parse '{:?}'", stringify!($var))  )

应该是,

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

format! creates a String, and .expect() takes a &str


感谢 Discord 上的 MEOW RAX, Nyathark Shill

正如您在自己的回答中提到的,expect 需要一个 &str,因此您不能直接传入 String

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

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

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

这实际上与上面的相同,期望 unwrap_or_else 仅在错误情况下调用其闭包。


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

的开销
.expect(concat!("Could not parse '", stringify!($var), "'"))