取决于环境的静态变量

时间:2018-06-23 12:32:02

标签: rust

我有一个结构,应该使用某个值将其初始化一次,然后可以自由引用(甚至跨线程共享)它而不会出现问题。问题是我想在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()))
}

但是,当我们知道直到程序退出时才删除引用时,这种情况以及引用计数看起来很奇怪。

0 个答案:

没有答案