我有一个结构,应该使用某个值将其初始化一次,然后可以自由引用(甚至跨线程共享)它而不会出现问题。问题是我想在hyper
回调的处理程序中使用它。这是我的示例代码:
extern crate futures; // 0.1.1
extern crate hyper; // 0.12
use std::net::SocketAddr;
use hyper::service::service_fn;
use hyper::{Body, Request, Response, Server};
use futures::prelude::*;
fn main() {
let token = std::env::args().next().unwrap();
run(&token, "127.0.0.1:8080");
}
fn run(bot_token: &str, listening_address: &str) {
let addr: SocketAddr = listening_address.parse().unwrap();
let server = Server::bind(&addr)
.serve(move || service_fn(|x| echo(x, bot_token)));
}
fn echo(
req: Request<Body>,
bot_token: &str
) -> impl Future<Item = Response<Body>, Error = hyper::Error> + Send {
futures::future::ok(Response::new(Body::empty()))
}
这里的问题是hyper
要求回调为static
:
error[E0621]: explicit lifetime required in the type of `bot_token`
--> src\main.rs:18:10
|
14 | fn run(bot_token: &str, listening_address: &str) {
| --------- consider changing the type of `bot_token` to `&'static str`
...
18 | .serve(move || service_fn(|x| echo(x, bot_token)))
| ^^^^^ lifetime `'static` required
error[E0621]: explicit lifetime required in the type of `bot_token`
--> src\main.rs:19:10
|
14 | fn run(bot_token: &str, listening_address: &str) {
| --------- consider changing the type of `bot_token` to `&'static str`
...
19 | .map_err(|e| eprintln!("server error: {}", e));
| ^^^^^^^ lifetime `'static` required
如果我遵循此建议并将telegram_client
的生存期更改为static
,则会收到一个错误,提示闭包可能会失效run
函数。
我应该如何避免呢?我发现我可以通过以下方式使其工作:
fn run(bot_token: &str, listening_address: &str) {
let addr: SocketAddr = listening_address.parse().unwrap();
let bot_token = Arc::new(bot_token.to_string());
let server = Server::bind(&addr)
.serve(move || {
let bot_token = bot_token.clone();
service_fn(move |x| echo(x, bot_token.clone()))
});
}
fn echo(
req: Request<Body>,
bot_token: Arc<String>
) -> impl Future<Item = Response<Body>, Error = hyper::Error> + Send {
futures::future::ok(Response::new(Body::empty()))
}
但是,当我们知道直到程序退出时才删除引用时,这种情况以及引用计数看起来很奇怪。