【问题标题】:.expect( format!() ): expected `&str`, found struct `String`.expect( format!() ): 预期 `&str`,找到结构 `String`
【发布时间】:2021-10-11 02:03:20
【问题描述】:

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

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看到这个

【问题讨论】:

  • 对输入错误的恐慌让我的蜘蛛侠感觉刺痛。尽量不要养成它的习惯。最好使用 ? 等来传播错误,就像 Clap 一样。既然您要创建Option&lt;u64&gt;,我可以建议parse::&lt;u64&gt;().ok()吗?
  • @JohnKugelman 没有宏,我假设 Rust 会告诉我期望在哪里,而不是当它说 "expected &amp;str, found struct String" 我当有人立即在 Discord 中回答它时,正试图创建一个宏。我想这是一个常见的问题?
  • @JohnKugelman 我刚刚知道了!我们去play.rust-lang.org/…

标签: rust macros


【解决方案1】:

正如您在自己的回答中提到的,expect 接受 &amp;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), "'"))

【讨论】:

  • unwrap_or_else() 的好建议,但请用{} 格式化错误,而不是{:?}。后者将通过其内部字段提供对用户不友好的错误类型表示,而不是面向用户的错误消息。
【解决方案2】:

我遇到的问题是

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

应该是,

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

format! 创建一个String.expect() takes a &amp;str


感谢 Discord 上的MEOW RAX, Nyathark Shill

【讨论】:

  • &amp;format!(...)
猜你喜欢
  • 1970-01-01
  • 2014-11-20
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 2019-08-03
  • 2020-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多