我正在尝试更改 Rust Tonic UDS gRPC 客户端示例。它包含以下代码块(请参阅链接):
let channel = Endpoint::try_from("http://[::]:50051")?
.connect_with_connector(service_fn(|_: Uri| async {
let path = "/tmp/tonic/helloworld";
// Connect to a Uds socket
Ok::<_, std::io::Error>(TokioIo::new(UnixStream::connect(path).await?))
}))
.await?;
更改非常简单:我只想能够从外部传入
path
而不是将其设置为固定值。问题是,它要么抱怨 service_fn
内部的函数比在其外部定义的任何 path
对象寿命更长。或者,如果我使用 move
传递它,它会抱怨 service_fn
需要一个 FnMut
,但现在我们给它一个 FnOnce
。
这两个错误对我来说都是有意义的:在我们超出了在该方法外部定义的任何
path
对象的生命周期之后很久,就可以从单独的线程调用该方法。而且,如果我们将其移动到函数中,则该移动只能完成一次,因此该函数不能再被多次调用,因为它可能需要为多个请求提供服务。
我在这里找到了一个答案,似乎完全符合我的需要,但我就是无法让它工作。我确信我错过了一些明显的东西,但我就是不知道它是什么。
您应该能够通过闭包
path
来捕获外部 move
变量。 到那时,你能用 path
做什么取决于未来的生命周期是如何限制的。 例如,这可能有效:
let move = todo!();
let channel = Endpoint::try_from("http://[::]:50051")?
.connect_with_connector(service_fn(move |_: Uri| async {
// Connect to a Uds socket
Ok::<_, std::io::Error>(TokioIo::new(UnixStream::connect(&path).await?))
}))
.await?;
但是,可能不会,因为未来可能不会被限制在关闭之后继续存在。 如果是这种情况,那么您需要将通往未来的路径的克隆移交给:
let move = todo!();
let channel = Endpoint::try_from("http://[::]:50051")?
.connect_with_connector(service_fn(move |_: Uri| {
let path = path .clone();
async move {
// Connect to a Uds socket
Ok::<_, std::io::Error>(TokioIo::new(UnixStream::connect(path).await?))
}
}))
.await?;