2

I use the cassandra of the c/c++ driver to query, and then return the data. Therefore, both cass (LinkedList) and cass_it (Vec) can show the result of the query. However, I want to display the results to the web using the json format, so I chose to reassemble the data using vec. However, there is a problem:

error[E0434]: can't capture dynamic environment in a fn item
   --> src/main.rs:306:42
    |
306 |         let out = serde_json::to_string(&cass_it).unwrap();
    |                                          ^^^^^^^
    |
    = help: use the `|| { ... }` closure form instead

What is wrong? Formatting issues?

Code:

fn main() {
    let mut cass = unsafe { cass_connect() };
    let mut cass_it = Vec::new();

    for cc in cass.iter() {
        cass_it.push(cc);
    }

    println!("{:?}", cass_it);

    let mut router = Router::new();
    let localhost = "localhost:3009".to_string();

    fn handler(req: &mut Request) -> IronResult<Response> {
        // convert the response struct to JSON
        let out = serde_json::to_string(&cass_it).unwrap();

        let content_type = "application/json".parse::<Mime>().unwrap();

        Ok(Response::with((content_type, status::Ok, out)))
    }

    router.get("/", handler, "index");

    info!("Listening on {}", localhost);
    Iron::new(router).http(localhost).unwrap();
}

Complete code

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
Chi Wei Shen
  • 307
  • 1
  • 2
  • 8
  • Please try to provide a [MCVE](https://stackoverflow.com/help/mcve), e.g. remove everything that is not necessary to produce the problem (remove the `info!` macro for example) and include all external crates you are using. – hellow Jan 24 '19 at 08:57
  • Btw: `= help: use the \`|| { ... }\` closure form instead` did you try that? – hellow Jan 24 '19 at 08:57
  • You've defined `handler` as a function (`fn handler …`) but you try to use variables that are local to the containing function (`main`). You can't do that. The compiler suggests using the closure form instead: `let handler = |req: &mut Request| -> IronResult { … }` – Jmb Jan 24 '19 at 13:24

1 Answers1

2

The error says it all:

can't capture dynamic environment in a fn item

The fn item in question is handler. Even though you have defined this function inside another method, a function declared with fn (a fn item) is compiled just like any other function on the top level of a module. Functions can't capture free variables from their environment; they can only access their explicit arguments and static variables.

The error goes on to say exactly which variable is the problem:

306 |   let out = serde_json::to_string(&cass_it).unwrap();
    |                                    ^^^^^^^

The variable cass_it is defined in the enclosing function and cannot be accessed from handler.

The note at the end of the error message then gives you a suggestion for how to fix the problem:

= help: use the `|| { ... }` closure form instead

A closure can capture variables from its environment. So you can try replacing the fn with a closure instead:

let handler = move |req: &mut Request| {
    // convert the response struct to JSON
    let out = serde_json::to_string(&cass_it).unwrap();
    let content_type = "application/json".parse::<Mime>().unwrap();
    Ok(Response::with((content_type, status::Ok, out)))
};

The move keyword will cause the closure to take ownership of cass_it instead of trying to reference the variable in the outer function.

Peter Hall
  • 53,120
  • 14
  • 139
  • 204
  • Thank you for answer.But,now there is "closure may outlive the current function, but it borrows `cass`, which is owned by the current function".why need use 'static'?about lifetime?(P.S.Because i change return type, so just use `cass `, remove `cass_it ` already) – Chi Wei Shen Jan 27 '19 at 14:35
  • @ChiWeiShen It's hard to help because the code you provided is not a [mcve], so I can't actually run your code. I have added something to explain how the `move` keyword will probably help. – Peter Hall Jan 27 '19 at 15:57
  • Hi, this is my [git](https://github.com/pili2026/cassandra-rs-driver).And, unconsciously, it can be executed on the web. However, I believe that more tests are needed. – Chi Wei Shen Jan 28 '19 at 02:54