Rust 带字符串的actix传递应用程序状态

Rust 带字符串的actix传递应用程序状态,rust,actix-web,Rust,Actix Web,您好,我想通过以下AppState pub struct AppState { clients: Vec<Client>, } 我希望我正在努力实现的目标是明确的。 现在来谈谈我的问题。 编译器说: 特性绑定的实体::CmkClientServerConfig:std::clone::clone在中不满足`[closure@src/server.rs:25:21:31:66 app_config:entities::CmkClientServerConfig] 由于异步执行

您好,我想通过以下AppState

pub struct AppState {
    clients: Vec<Client>,
}
我希望我正在努力实现的目标是明确的。 现在来谈谈我的问题。 编译器说:

特性绑定的
实体::CmkClientServerConfig:std::clone::clone
在中不满足`[closure@src/server.rs:25:21:31:66 app_config:entities::CmkClientServerConfig]

由于异步执行,可能需要克隆这个东西。 因此,在CmkClientServerConfig结构和客户端结构中添加了“#[派生(克隆)]”

然后,获取此错误消息:

error[E0507]: cannot move out of `app_config.clients`, as `app_config` is a captured variable in an `Fn` closure
  --> src/server.rs:29:22
   |
23 | async fn launch_server(app_config: CmkClientServerConfig) -> std::io::Result<()> {
   |                        ---------- captured outer variable
...
29 |             clients: app_config.clients
   |                      ^^^^^^^^^^^^^^^^^^ move occurs because `app_config.clients` has type `std::vec::Vec<entities::Client>`, which does not implement the `Copy` trait

error[E0507]: cannot move out of `app_config.clients`, as `app_config` is a captured variable in an `Fn` closure
  --> src/server.rs:29:22
   |
23 | async fn launch_server(app_config: CmkClientServerConfig) -> std::io::Result<()> {
   |                        ---------- captured outer variable
...
29 |             clients: app_config.clients
   |                      ^^^^^^^^^^^^^^^^^^ move occurs because `app_config.clients` has type `std::vec::Vec<entities::Client>`, which does not implement the `Copy` trait
error[E0507]:无法移出'app\u config.clients',因为'app\u config'是'Fn'闭包中捕获的变量
-->src/server.rs:29:22
|
23 |异步fn启动服务器(应用程序配置:CmkClientServerConfig)->std::io::结果{
|-------捕获的外部变量
...
29 |客户端:app_config.clients
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
错误[E0507]:无法移出'app_config.clients',因为'app_config'是'Fn'闭包中捕获的变量
-->src/server.rs:29:22
|
23 |异步fn启动服务器(应用程序配置:CmkClientServerConfig)->std::io::结果{
|-------捕获的外部变量
...
29 |客户端:app_config.clients
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
我的问题是如何正确地做,如何使克隆成为可能

感谢您的帮助。

和解释:

HttpServer
接受应用程序工厂而不是应用程序实例。
HttpServer
为每个线程构建一个应用程序实例。因此,应用程序数据必须多次构建。如果要在不同线程之间共享数据,则应创建一个可共享对象d可以使用,例如
Send+Sync

如果您的
客户端
列表仅在服务器启动时初始化,否则保持不变,则您可以在应用程序工厂功能中克隆它,但如果假定它是可变的,则必须将其包装在
中,以便在运行应用程序的多个线程之间安全地克隆、共享和变异ng>

如果
客户端
列表没有更改,则将客户端更新为
派生
克隆特征:

#[派生(序列化、反序列化、调试、克隆)]//此处添加克隆
发布结构客户端{
pub id:String,
发布密码:String,
}
然后将你的应用程序工厂功能更新为将你的
应用程序配置
移动到自身中,这样你就可以在
客户端
上重复调用
克隆

异步fn启动服务器(应用程序配置:CmkClientServerConfig)->std::io::结果{ HttpServer::new(move | | App::new()//此处添加了move .data(Config::default().realm(“受限区域”)) .数据(AppState){ 客户端:app_config.clients.clone()//此处添加了clone() }) .app_数据(web::PayloadConfig::new(1000000)) .service(web::resource(“/”).route(web::post().to(index))) .bind(“127.0.0.1:8080”)? .工人(1) .run() .等待 } 和解释:

HttpServer
接受应用程序工厂而不是应用程序实例。
HttpServer
为每个线程构建一个应用程序实例。因此,应用程序数据必须多次构建。如果要在不同线程之间共享数据,则应创建一个可共享对象d可以使用,例如
Send+Sync

如果您的
客户端
列表仅在服务器启动时初始化,否则保持不变,则您可以在应用程序工厂功能中克隆它,但如果假定它是可变的,则必须将其包装在
中,以便在运行应用程序的多个线程之间安全地克隆、共享和变异ng>

如果
客户端
列表没有更改,则将客户端更新为
派生
克隆特征:

#[派生(序列化、反序列化、调试、克隆)]//此处添加克隆
发布结构客户端{
pub id:String,
发布密码:String,
}
然后将你的应用程序工厂功能更新为将你的
应用程序配置
移动到自身中,这样你就可以在
客户端
上重复调用
克隆

异步fn启动服务器(应用程序配置:CmkClientServerConfig)->std::io::结果{ HttpServer::new(move | | App::new()//此处添加了move .data(Config::default().realm(“受限区域”)) .数据(AppState){ 客户端:app_config.clients.clone()//此处添加了clone() }) .app_数据(web::PayloadConfig::new(1000000)) .service(web::resource(“/”).route(web::post().to(index))) .bind(“127.0.0.1:8080”)? .工人(1) .run() .等待 }
我认为您需要解决移动
app\u config.clients
的问题。只要您在同一页面上,传递给
HttpServer::new
的clojure将在每个线程执行一次。因此,这将导致多个移动出
app\u config.clients
(仔细想想,您就会明白actix是如何工作的)

也就是说,根据可能的情况,可以通过以下方式之一处理此问题:

  • 为每个线程创建新的
    Vec
    ,如下所示:
  • 。。。
    .数据(AppState){
    客户端:创建新的客户端()
    })
    
  • 如果您的
    客户端
    结构是
    克隆
    ,您还可以执行以下操作:
  • 。。。
    .数据(AppState){
    客户端:app_config.clients.clone()
    })
    
  • 所有其他
    #[derive(Serialize, Deserialize, Debug)]
    pub struct Client {
        pub id: String,
        pub password: String,
    }
    
    error[E0507]: cannot move out of `app_config.clients`, as `app_config` is a captured variable in an `Fn` closure
      --> src/server.rs:29:22
       |
    23 | async fn launch_server(app_config: CmkClientServerConfig) -> std::io::Result<()> {
       |                        ---------- captured outer variable
    ...
    29 |             clients: app_config.clients
       |                      ^^^^^^^^^^^^^^^^^^ move occurs because `app_config.clients` has type `std::vec::Vec<entities::Client>`, which does not implement the `Copy` trait
    
    error[E0507]: cannot move out of `app_config.clients`, as `app_config` is a captured variable in an `Fn` closure
      --> src/server.rs:29:22
       |
    23 | async fn launch_server(app_config: CmkClientServerConfig) -> std::io::Result<()> {
       |                        ---------- captured outer variable
    ...
    29 |             clients: app_config.clients
       |                      ^^^^^^^^^^^^^^^^^^ move occurs because `app_config.clients` has type `std::vec::Vec<entities::Client>`, which does not implement the `Copy` trait