如何使 Result 的内部值必须使用

cam*_*024 3 rust

我可以使用该#[must_use]属性将函数标记为具有必须使用或显式忽略的返回值:

#[must_use]
fn plain() -> i32 {
  1
}

fn main() {
  plain();  // warning
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我想更改我的函数,使其现在返回 a Result,我不能这样做:

#[must_use]
fn result() -> Result<i32, ()> {
  Ok(1)
}

fn main() {
  result().unwrap();
}
Run Code Online (Sandbox Code Playgroud)

因为对的调用.unwrap()算作“使用”,并且该#[must_use]属性应用于整个Result.

有没有办法#[must_use]也适用于内部类型?本质上我想确保i32不会意外地被分号“吃掉”。

我有一个额外的限制,即我无法更改此函数的公共 API,因此我无法让它返回 aResult<MustUse<i32>, ()>或类似的内容。

cdh*_*wie 5

您无法通过直接向 中添加自己的注释来做到这一点Result,但您可以使用 newtype 轻松完成此操作:

#[must_use]
#[repr(transparent)]
pub struct MustUse<T>(T);

impl<T> From<T> for MustUse<T> {
    fn from(v: T) -> Self {
        Self(v)
    }
}

impl<T> MustUse<T> {
    #[must_use]
    fn into_inner(self) -> T {
        self.0
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,鉴于此声明:

fn result() -> Result<MustUse<i32>, ()> {
  Ok(1.into())
}
Run Code Online (Sandbox Code Playgroud)

以下所有情况都会导致警告:

  • result();警告因为Result<_, _>必须使用。
  • result().unwrap();警告因为MustUse<_>必须使用。
  • result().unwrap().into_inner();警告因为MustUse<_>::into_inner()必须使用。

(请注意,您可以通过调用 的不同的、非必须使用的方法Result(例如 )来绕过警告result().ok(),但无论您做什么,这都是正确的。)