I get a rust compiler error:
src/main.rs:33:31: 33:35 error: can't capture dynamic environment in a fn item; use the || { ... } closure form instead
The error occurs because I have a function in which I declare a variable using let
, and then have an inner function in which I try to use this variable that is closed over.
I am fairly certain that this is a beginner question, so sorry in advance if this has a very straight forward answer!
Note that I am using this inner function as a callback somewhere, and thus using a closure, like
let closure_fn = | args | -> () { do stuff };
... is not going to be an appropriate solution for me.
extern crate nickel;
use std::io::net::ip::Ipv4Addr;
use nickel::{ Nickel, Request, Response };
fn stub_3rd_party_function() -> String {
"hello world".to_string()
}
fn main() {
let mut server = Nickel::new();
// assume that the variable **must** be instantiated like this
let hello_text : String = stub_3rd_party_function();
fn hello_handler (_request: &Request, response: &mut Response) -> () {
response.send(hello_text.as_slice());
}
server.get("/hello", hello_handler);
server.listen(Ipv4Addr(0,0,0,0), 6767);
}
Results in the following error:
src/test.rs:12:23: 12:33 error: can't capture dynamic environment in a fn item; use the || { ... } closure form instead
src/test.rs:12 response.send(hello_text);
^~~~~~~~~~
src/test.rs:12:23: 12:33 error: unresolved name `hello_text`.
src/test.rs:12 response.send(hello_text);
^~~~~~~~~~
error: aborting due to 2 previous errors
Now, I switch from a standard function to a closure function instead:
extern crate nickel;
use std::io::net::ip::Ipv4Addr;
use nickel::{ Nickel, Request, Response };
fn stub_3rd_party_function() -> String {
"hello world".to_string()
}
fn main() {
let mut server = Nickel::new();
// assume that the variable **must** be instantiated like this
let hello_text : String = stub_3rd_party_function();
let hello_handler = |_request: &Request, response: &mut Response| -> () {
response.send(hello_text.as_slice());
};
server.get("/hello", hello_handler);
server.listen(Ipv4Addr(0,0,0,0), 6767);
}
Results in a different error:
src/test.rs:21:30: 21:43 error: mismatched types: expected `fn(&nickel::request::Request<'_>, &mut nickel::response::Response<'_,'_>)` but found `|&nickel::request::Request<'_>, &mut nickel::response::Response<'_,'_>|` (expected extern fn but found fn)
src/test.rs:21 server.get("/hello", hello_handler);
^~~~~~~~~~~~~
error: aborting due to previous error
Is there perhaps a way to "wrap" the closed over function with a normal one?
Since the library that I am using expects a standard function instead of a closure,
I cannot use a closure.
But if I do not use a closure, I cannot close over variables that are defined within the outer function, fn main () { ... }
... and thus getting stuck here.
Note that above, I am using a string, hello_text
, for the purposes of providing a concise code example.
In this case using a static variable would suffice. However, static variables will not fix it for me, as I need to be able to assign a variable from within a fn main()
the result of a function call, and then use that within my inner handler function.