下面是它的实际示例:
let msg = stream.next().await.context("expected a message")??;
只是?
做两次吗?如果是这样,为什么在这种情况下需要这样做?
是的,它只是?
被执行两次;没有??
运算符。
stream
是一个WsStream
.WsStream
是在同一模块中定义的类型。WsStream
实现Stream
.
stream.next()
调用StreamExt::next
,返回产生Option<Self::Item>
的未来。Self::Item
被定义为WsStream
的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
它大约是unwrap()
或try!
的运算符,所以这可以扩展到类似的东西:
let msg = try!(stream.next().await.context("expected a message")).unwrap();
使用异步代码,您将经常看到await?
,但await??
看起来确实很奇怪。