【发布时间】:2020-07-03 22:33:05
【问题描述】:
这是action中的一个例子:
let msg = stream.next().await.context("expected a message")??;
只是? 被执行了两次吗?如果是这样,为什么在这种情况下需要这样做?
【问题讨论】:
标签: rust operator-keyword
这是action中的一个例子:
let msg = stream.next().await.context("expected a message")??;
只是? 被执行了两次吗?如果是这样,为什么在这种情况下需要这样做?
【问题讨论】:
标签: rust operator-keyword
是的,只是? 被执行了两次;没有?? 运算符。
stream 是 WsStream。 WsStream 是在同一模块中定义的类型。 WsStream 实现 Stream。
stream.next() 调用 StreamExt::next,它返回一个产生 Option<Self::Item> 的未来。对于WsStream,Self::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>。因此? 的两种用法用于处理Results 的两个级别。
【讨论】:
是的,这只是 ? 运算符执行了两次。一个简单的例子:
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
【讨论】:
它大约是一个operator for unwrap() or try!,因此可以将其扩展为:
let msg = try!(stream.next().await.context("expected a message")).unwrap();
使用异步代码,您会经常看到await?,但await?? 看起来确实很奇怪。
【讨论】: