如何在 Rust 中引用 impl 输出的类型?

mwlon

我正在尝试在 Rust 中实现一个流以用于 tonic GRPC 处理程序并遇到了这个困难:创建流的大多数方法都没有易于表达的类型,但我需要实现的 GRPC 特征需要特定的 Stream 类型。像这样的东西(简化):

// trait to implement
trait GrpcHandler {
  type RespStream: futures::Stream<ResponseType> + Send + 'static
  fn get_resp_stream() -> Self::RespStream;
}

// a start at implementing it
impl GrpcHandler for MyHandler {
  type RespStream = ???; // what do I put here?
  fn get_resp_stream() -> Self::RespStream {
    futures::stream::unfold((), |_| async {
      tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
      Some((ResponseType {}, ()))
    })
  }
}

我知道我的流的类型在技术上类似于Unfold<(), ComplicatedFnSignatureWithImpl, ComplicatedFutureSignatureWithImpl>,但即使我输入了整个内容,编译器也不会因为它是不透明类型而高兴。如何引用此流的类型?

查伊姆弗里德曼

不幸的是,如果没有动态调度,在稳定的 Rust 中没有好的方法可以做到这一点。您必须使用dyn Stream, 并为此futures提供BoxStream

impl GrpcHandler for MyHandler {
    type RespStream = futures::stream::BoxStream<'static, ResponseType>;
    fn get_resp_stream() -> Self::RespStream {
        futures::stream::unfold((), |_| async {
            tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
            Some((ResponseType {}, ()))
        })
        .boxed()
    }
}

如果你使用 nightly,你可以使用不稳定的type_alias_impl_trait特性来避免动态调度的开销:

#![feature(type_alias_impl_trait)]

impl GrpcHandler for MyHandler {
    type RespStream = impl futures::Stream<Item = ResponseType> + Send + 'static;
    fn get_resp_stream() -> Self::RespStream {
        futures::stream::unfold((), |_| async {
            tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
            Some((ResponseType {}, ()))
        })
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章