如何在 Rust 的闭包内重用外部作用域的值?

How to re-use a value from the outer scope inside a closure in Rust?

我正在尝试在一个小的 Rust 程序中添加网络服务器 (hyper),但我遇到了移动问题。

//main.rs

    // Suppose this is something meaningful and used in multiple places inside `main`
    let test: String = "Foo".to_string();

// ...

// This comes from here: https://docs.rs/hyper/0.14.8/hyper/service/fn.service_fn.html
// Determines what the web server sends back

    let make_svc = make_service_fn(|_conn| async {
        Ok::<_, Infallible>(service_fn(|req: Request<Body>| async move {
            // I need to somehow read the value of `test` here as well
            if req.version() == Version::HTTP_11 {
                Ok(Response::new(Body::from(test)))
            } else {
                Err("not HTTP/1.1, abort connection")
            }
        }))
    });

这会产生以下问题:

我知道 String 不能具有 Copy 特性(最终我将需要使用其他更复杂的类型)。本质上,我想借用或使用变量的克隆,因为变量也将在 hyper 的处理程序之外使用(例如,它可以记录到文件或用于随时间的聚合统计)。

所以我的问题是,它是如何工作的?我需要如何重构闭包,以便我可以以某种方式访问​​在 main 中定义(和以其他方式使用)的变量的值?

如果你想克隆 test 那么你需要在闭包外克隆它,然后将它移动到闭包中。请注意,如果您想稍后更改测试并将这些更改反映在闭包内,您将需要使用 Arc 以便闭包内外都可以对同一字符串进行可变访问。

fn main() {
    let mut test: String = "Foo".to_string();

    // Clone the string so you can use it in a closure.
    let test_for_closure = test.clone();
    let closure = || {
        println!("{}", test_for_closure);
    };

    // You can still use test outside the closure
    println!("{}", test); // prints "Foo"
    closure(); // prints "Foo"

    // But if test is changed, test_for_closure will not change
    test = "Other".to_string();
    println!("{}", test); // prints "Other"
    closure(); // prints "Foo"
}

如果您需要有关使用 Arc 对同一字符串进行共享可变访问的帮助,请告诉我。