什么?生锈了吗?

What does ?? do in rust?

这是 action 中的一个例子:

let msg = stream.next().await.context("expected a message")??;

只是 ? 完成了两次吗?如果是这样,为什么在这种情况下需要这样做?

大约是 operator for unwrap() or try!,因此可以扩展为:

let msg = try!(stream.next().await.context("expected a message")).unwrap();

使用异步代码,您会经常看到 await?,但 await?? 确实看起来很奇怪。

是的,只是 ? 完成了两次;没有 ?? 运算符。

stream 是一个 WsStreamWsStream 是同一模块中定义的类型。 WsStream 实施 Stream.

stream.next() 调用 StreamExt::next,returns 产生 Option<Self::Item> 的未来。对于 WsStreamSelf::Item 定义为 tungstenite::Result<Message> (= Result<Message, tungstenite::Error>)。这意味着 stream.next().await 的结果是 Option<Result<Message, tungstenite::Error>>.

类型

然后,context 应用于该值。 Context 是为 Option<T>Result<T, E> 实现的,但输出始终是 Result。然而,context 并没有压平任何东西,所以我们最终得到 Result<Result<Message, tungstenite::Error>, anyhow::Error>。因此,? 的两个用途用于处理 Result 的两个级别。

是的,只是 ? 运算符完成了两次。一个简单的例子:

fn result_of_result() -> Result<Result<i32, String>, String> {
    Ok(Ok(42))
}

fn f() -> Result<(), String> {
    println!("{:?}", result_of_result());
    println!("{:?}", result_of_result()?);
    println!("{:?}", result_of_result()??);
    Ok(())
}

fn main() {f();}

输出:

Ok(Ok(42))
Ok(42)
42