0

我对 Rust 编程还很陌生,并且仍在尝试理解有关内存和所有权的概念。

我有这个代码。

#[tokio::main]
async fn main() {

    let file_root = String::from("test_dir/");
    let content_dir = String::from("posts_");
    let obj = msgnode::MsgNode::new(file_root.clone(), content_dir.clone());

    let node_filter = warp::any().map(move || obj.clone());

    // GET /hello/warp => 200 OK with body "Hello, warp!"
    let hello = warp::get()
        .and(warp::path("waservice"))
        .and(warp::path::end())
        .and(msg_body())
        .and(node_filter.clone())
        .and_then(store_wamsg);

    warp::serve(hello)
        .run(([127, 0, 0, 1], 3030))
        .await;
}

mod msgnode;

一切都很好,除了我不能使用克隆的MsgNode对象实例。在 store_wamsg 中,我使用 MsgNode 对象,如下所示:

async fn store_wamsg(item: MsgItem, node : &msgnode::MsgNode) -> Result<impl warp::Reply, warp::Rejection> {
    
    let mut node2 = node.clone();

    node2.create_file(item.msg_content);
    
    Ok(warp::reply::with_status(
        "All good",
        http::StatusCode::OK,
    ))
}

我的问题是,如果有一种方法我不需要在主函数中使用 MsgNode 对象的多个克隆实例,那么每次对服务发出新请求时?

更准确地说,我想做这样的事情:

let node_filter = warp::any().map(move || &obj);

并以某种方式在 store_wamsg 函数中传递引用。现在,当我这样做时,我遇到了以下错误:

116 |     let node_filter = warp::any().map(move || &obj);
    |                                       ------- ^^^^ returning this value requires that `'1` must outlive `'2`  
    |                                       |     |
    |                                       |     return type of closure is &'2 MsgNode
    |                                       lifetime `'1` represents this closure's body
    |
    = note: closure implements `Fn`, so references to captured variables can't escape the closure
4

1 回答 1

2

您可以封装 msgnodeArc Mutex以同步访问:

use std::sync::{Arc, Mutex};

let obj = Arc::new(Mutex::new(msgnode::MsgNode::new(
    file_root.clone(),
    content_dir.clone(),
)));

let node_filter = warp::any().map(move || obj.clone());

在这里,obj.clone()克隆原子资源计数器,而不是 msgnode。因此只有一个 MsgNode 实例,并且线程在 Arc 和 Mutex 的帮助下协调对它的访问。

于 2022-02-20T03:23:21.043 回答