无法移动借用内容

5

req.url.fragment是一个可选的String。如果它有值,我想将该值复制到fragment中,否则我想分配一个空字符串。但是我一直收到错误消息,提示我无法移动借用内容

我该如何解决这个问题?

fn fb_token(req: &mut Request) -> IronResult<Response> {
    let fragment = match req.url.fragment {
        Some(fragment) => fragment,
        None => "".to_string(),
    };

    Ok(Response::with((status::Ok, fragment)))
}
2个回答

13

这取决于您想要如何处理结构中的现有字符串。

let fragment = match req.url.fragment {
    Some(fragment) => fragment,
    None => "".to_string(),
};
在这段代码中,你正在将字符串从req.url.fragment移出,但这会使它处于未定义状态。这是不好的事情,Rust会阻止你这样做!
正如错误信息所述:
为了防止移动,请使用ref fragmentref mut fragment通过引用捕获值。
如果你想保留字符串并返回一个副本,那么你可以先取一个引用,然后进行克隆:
let fragment = match req.url {
    Some(ref fragment) => fragment.clone(),
    None => "".to_string()
};

如果您想将现有的字符串保留为 None,则可以使用 take

let fragment = match req.url.take() {
    Some(fragment) => fragment,
    None => "".to_string()
};

更简洁的方法是使用 unwrap_or_else

let fragment = req.url.take().unwrap_or_else(String::new);

我确实理解了关于借用如何冻结所引用的对象的事情,这意味着在这种情况下不允许移动,但我就是想不出如何避免移动。显然,我需要重新审查一些概念并仔细阅读文档。谢谢你的帮助 :) - W.K.S

2
这里的问题在于无法使 &mut 引用失效,而移动所有权是使之无效的一种方式。(右侧边栏上有几个类似问题/答案的链接。)
解决方法是改用引用,在这种情况下应该很有效:
fn fb_token(req: &mut Request) -> IronResult<Response> {
    let fragment: &str = match req.url.fragment {
        Some(ref fragment) => &**fragment,
        None => "",
    };

    Ok(Response::with((status::Ok, fragment)))
}

&str注释不是必需的,只是为了更清楚地说明正在发生什么。)
这是有效的,因为Iron实现了Modifier<Response>以支持& str,所以该类型可以与with一起使用,而不是拥有的String

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接