Rust 克隆 HashMap<String, Object> 而不进入闭包

Rust cloning HashMap<String, Object> without moving into closure

我正在尝试用 Rust 创建我自己的编程语言,并且大多数功能都已完成,所以我想我可以在 UnknownIdentifier 错误中添加找到与用户想要的最接近的匹配项的能力

然而,在我找到最接近的匹配之前,我发现克隆 HashMap 将它移到了闭包中

ErrorGenerator::错误函数:

#[allow(non_snake_case)]
mod ErrorGenerator {
    pub fn error(name: &str, explanation: &str, line: usize, col: usize, file: String, after_f: Box<dyn Fn() -> ()>) -> ! {
        eprintln!("\n[ERROR] {}, Line {:?}, Column {:?}", file, line, col);
        eprintln!("    {}: {}", name, explanation);
        after_f();
        exit(1);
    }
}
ErrorGenerator::error(
    "UnknownIdentifier",
    &format!("unknown identifier: `{}`, this identifier could not be found", tokenc.repr()),
    tokenc.line,
    tokenc.col,
    tokenc.file,
    Box::new(||{
        let mut hashc: Vec<String> = hashs.clone().into_keys().collect();
        hashc.sort();
    }),
);

这是它给出的错误:

error[E0597]: `hashs` does not live long enough
    --> src/runtime/runtime.rs:960:70
     |
959  |                                       Box::new(||{
     |                                       -        -- value captured here
     |  _____________________________________|
     | |
960  | |                                         let mut hashc: Vec<String> = hashs.clone().into_keys().collect();
     | |                                                                      ^^^^^ borrowed value does not live long enough
961  | |                                         hashc.sort();
962  | |                                     }),
     | |______________________________________- cast requires that `hashs` is borrowed for `'static`
...
1203 |       }
     |       - `hashs` dropped here while still borrowed

问题的解决方案可能是:

您可以在 https://github.com/kaiserthe13th/tr-lang/tree/unknown-id-err-impl

中找到完整代码

发生的事情是编译器没有克隆 hashs 然后将克隆传递给您的回调;相反,它将对 hashs 的引用传递给您的回调并将其克隆 在回调 .

但是,回调必须是 'static,如果它包含对包含函数的引用,则不是!所以编译器在抱怨。

你想要的是在之前克隆hashmap,然后将克隆传递给回调。喜欢:

ErrorGenerator::error(
    "UnknownIdentifier",
    &format!("unknown identifier: `{}`, this identifier could not be found", tokenc.repr()),
    tokenc.line,
    tokenc.col,
    tokenc.file,
    {
        let hashc = hashs.clone();
        Box::new(|| {
            let mut hashc: Vec<String> = hashc.into_keys().collect();
            hashc.sort();
        })
    },
);

如果您这样做,您还会认识到闭包需要 FnOnce(),因为您要离开 hashc (.into_keys())。所以 after_f: Box<dyn FnOnce()>.