【问题标题】:What does ?? do in rust?有什么作用??生锈吗?
【发布时间】:2020-07-03 22:33:05
【问题描述】:

这是action中的一个例子:

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

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

【问题讨论】:

    标签: rust operator-keyword


    【解决方案1】:

    是的,只是? 被执行了两次;没有?? 运算符。

    streamWsStreamWsStream 是在同一模块中定义的类型。 WsStream 实现 Stream

    stream.next() 调用 StreamExt::next,它返回一个产生 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>。因此? 的两种用法用于处理Results 的两个级别。

    【讨论】:

      【解决方案2】:

      是的,这只是 ? 运算符执行了两次。一个简单的例子:

      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
      

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-20
          • 1970-01-01
          • 2013-05-05
          • 2023-01-30
          • 2021-09-20
          • 2016-01-13
          • 2011-10-09
          • 1970-01-01
          相关资源
          最近更新 更多