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

4
我正在尝试在Rust中实现一个流(stream),以在tonic GRPC处理程序中使用,但我遇到了这个困难:大多数创建流的方式没有易于表达的类型,然而我需要实现的GRPC trait需要特定的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>,但即使我键入了整个字符串,编译器也不会接受它是一个不透明类型。如何引用此流的类型?

1个回答

6

很遗憾,在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 {}, ()))
        })
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接