< 返回版块

Pikachu 发表于 2021-07-18 03:40

Tags:actix-web, ownership, move

我在尝试使用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的角度理解编译器为什么阻止了我,求大佬讲解。

评论区

写评论
作者 Pikachu 2021-07-18 04:36

我自己搞懂了。

首先是cloneHttpServerfactory的bound是Fn。而如果不加clone的话,整个闭包的类型是FnOnce,因为resApp.data里被consume了。

然后是move。这个的原因是闭包被传递给了另一个函数,所以不允许按引用捕获。而默认情况下,闭包选择最保守的捕获方式,在题目例子里是按不可变引用捕获。

1 共 1 条评论, 1 页