我在尝试使用actix-web
,写了如下的代码。
use actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};
#[get("/")]
async fn hello(addr: web::Data<Addr<Game>>) -> impl Responder {
HttpResponse::Ok().body("Hello world!")
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let res = "string".to_string();
HttpServer::new(move || {
App::new()
.service(hello)
.data(res.clone())
})
.bind("127.0.0.1:8080")?
.run()
.await
}
相关库的版本是
[dependencies]
actix-web = "3"
上面这个版本的代码是能够运行的。我的困惑在于main
函数的第3-7行:这里我按照编译器的提示,先加上了move
,又加上了res.clone()
。如果我去掉了任何一个,编译器就会报错,我不太理解问题出现的原因。
目前有一点模糊的猜测,就是App.data的文档上写的,server会创建多个worker,每个worker会有独立的state实例,所以直接move不可行。但是我没法从ownership和trait bounds的角度理解编译器为什么阻止了我,求大佬讲解。
1
共 1 条评论, 1 页
评论区
写评论我自己搞懂了。
首先是
clone
。HttpServer对factory
的bound是Fn
。而如果不加clone的话,整个闭包的类型是FnOnce
,因为res
在App.data
里被consume了。然后是
move
。这个的原因是闭包被传递给了另一个函数,所以不允许按引用捕获。而默认情况下,闭包选择最保守的捕获方式,在题目例子里是按不可变引用捕获。