首页 > 解决方案 > .expect( format!() ): 预期 `&str`,找到结构 `String`

问题描述

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

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

我已经在Clap withvalues_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 示例中看到这一点

标签: rustmacros

解决方案


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

.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), "'"))

推荐阅读