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



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

// 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()
}
}

如果你使用夜间,你可以使用不稳定的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 {}, ()))
})
}
}

最新更新