【问题标题】:How to re-use a value from the outer scope inside a closure in Rust?如何在 Rust 的闭包内重用外部范围的值?
【发布时间】:2021-06-06 14:49:46
【问题描述】:

我正在尝试在一个小型 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 中定义(以及以其他方式使用)的变量的值?

【问题讨论】:

  • 你可以克隆它,或者例如创建一个Arc
  • @Netwave 我尝试在内部和外部克隆它,但仍然是同样的问题。我会研究 Arc,谢谢!

标签: rust hyper


【解决方案1】:

如果要克隆测试,则需要将其克隆到闭包之外,然后将其移动到闭包中。请注意,如果您想稍后更改测试并将这些更改反映在闭包内,您将需要使用 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 对同一字符串进行共享可变访问的帮助,请告诉我。

【讨论】:

  • 非常感谢!对于解释和例子,我想我现在明白了!不过,我遇到了线程安全错误,如果你有多余的精力,我在这里打开了一个新 Q:stackoverflow.com/questions/67877287/…
猜你喜欢
  • 1970-01-01
  • 2012-08-22
  • 1970-01-01
  • 2020-12-17
  • 2012-11-03
  • 2016-06-23
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多