You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust报错cannot move out of an `Arc`,调用Routing的get_route方法如何解决?

问题根源

你的get_route和get_relevant_map方法的第一个参数使用了值语义的self,调用时会消耗Routing实例的所有权。但你的Routing实例被包裹在Arc中共享,Arc不允许你将内部的值移出(除非你是唯一持有者,显然多线程处理请求的场景下不满足这个条件),因此触发了E0507错误。

最优解决方案(推荐)

直接修改Routing的方法签名,使用不可变引用&self代替所有权转移的self,你的两个方法本质都是只读操作,完全不需要消耗实例:

impl Routing {
    // 其余方法保持不变

    #[inline(always)]
    // 修改参数为&self,对应的成员clone后返回即可
    fn get_relevant_map(&self, route: &Method) -> Option<Node<PyFunction>> {
        match route {
            &Method::GET => Some(self.get_routes.clone()),
            &Method::POST => Some(self.post_routes.clone()),
            &Method::PUT => Some(self.put_routes.clone()),
            &Method::PATCH => Some(self.patch_routes.clone()),
            &Method::DELETE => Some(self.delete_routes.clone()),
            &Method::HEAD => Some(self.head_routes.clone()),
            &Method::OPTIONS => Some(self.options_routes.clone()),
            &Method::CONNECT => Some(self.connect_routes.clone()),
            &Method::TRACE => Some(self.trace_routes.clone()),
            _ => None,
        }
    }

    #[inline(always)]
    // 同样修改参数为&self
    pub fn get_route(&self, route_method: &Method, route: &str) -> Option<PyFunction> {
        println!("Hello world how are your");
        let table = self.get_relevant_map(route_method)?;

        match table.at(route) {
            Ok(res) => Some(res.value.clone()),
            Err(_) => None,
        }
    }
}

修改后调用逻辑可以直接简化为:

async fn index(
    router: web::Data<Arc<Routing>>,
    headers: web::Data<Arc<Headers>>,
    mut payload: web::Payload,
    req: HttpRequest,
) -> impl Responder {
    match router.get_route(req.method(), req.uri().path()) {
        Some(handler_function) => {
            return handle_request(&handler_function, &headers, &mut payload, &req).await
        }
        None => {
            let mut response = HttpResponse::Ok();
            apply_headers(&mut response, &headers);
            return response.finish();
        }
    }
}
替代解决方案(无需修改Routing定义)

如果你不方便改动Routing结构体的方法实现,可以手动克隆一份Arc内部的Routing实例,消耗克隆出来的独立实例即可:

async fn index(
    router: web::Data<Arc<Routing>>,
    headers: web::Data<Arc<Headers>>,
    mut payload: web::Payload,
    req: HttpRequest,
) -> impl Responder {
    // 克隆出独立的Routing实例,调用方法时消耗克隆的实例,不影响原Arc中的共享数据
    let routing_clone = router.as_ref().clone();
    match routing_clone.get_route(req.method(), req.uri().path()) {
        Some(handler_function) => {
            return handle_request(&handler_function, &headers, &mut payload, &req).await
        }
        None => {
            let mut response = HttpResponse::Ok();
            apply_headers(&mut response, &headers);
            return response.finish();
        }
    }
}

内容的提问来源于stack exchange,提问作者Sanskar Jethi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 13:18:04