我一直试图在异步助手之间共享(只读)数据结构。我要完成的工作是创建一个超级服务器,在其中我预先生成一些可以供所有请求处理程序使用的数据。
以下是《超级入门指南》中的示例,并扩展了我想做的事情:
#[tokio::main]
async fn main() {
let address = SocketAddr::from(([127, 0, 0, 1], 3000));
let pages = generate_static_pages();
let make_service = make_service_fn(|_conn| async move {
Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
serve(pages, req)
}))
});
let server = Server::bind(&address).serve(make_service);
if let Err(error) = server.await {
eprintln!("server error: {}", error);
}
}
就我而言,generate_static_pages()
返回一个HashMap<&'static str, Bytes>
,其中包含预先生成的页面。不幸的是,无法在编译时生成此哈希映射,因为这会使事情变得容易得多。现在,我很努力,因为闭包不能借用pages
:“不能移出pages
闭包中捕获的变量FnMut
”
我试图传递一个引用,但这没有用,因为Rust无法推断出该变量存在足够长的时间以供闭包使用。然后,我尝试使用.clone()
,但这不起作用,因为它将在变量移动后在变量上调用,但不能。最后,我尝试用Arc
换行,但这并不能解决问题,基本上是出于相同的原因。
您会建议我做什么?谢谢!
答案 0 :(得分:1)
如果您只希望对页面进行不变的引用,则应该可以使用lazy_static
条板箱。 lazy_static
使您可以在运行时初始化静态变量-这非常有用!
您的代码最终看起来像:
use lazy_static::lazy_static;
lazy_static! {
static ref PAGES: HashMap<&'static str, Bytes> = generate_static_pages();
}
#[tokio::main]
async fn main() {
let address = SocketAddr::from(([127, 0, 0, 1], 3000));
let make_service = make_service_fn(|_conn| async move {
Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
serve(&PAGES, req)
}))
});
let server = Server::bind(&address).serve(make_service);
if let Err(error) = server.await {
eprintln!("server error: {}", error);
}
}
另外,这里还有另一个lazy_static
example。