How to Have a Function Return a Closure That Captures The Environment?

Can anybody help me figure out how to get a function to return a closure that captures the function's environment? This is my current attempt, but it won't compile.

fn main() {

fn test_func<F: FnOnce() -> String>(arg: String) -> F
    || arg



   Compiling playground v0.0.1 (/playground)
error[E0282]: type annotations needed
 --> src/
2 |     dbg!(test_func("test".into())());
  |          ^^^^^^^^^ cannot infer type for `F`
  = note: type must be known at this point

error[E0308]: mismatched types
 --> src/
5 | fn test_func<F: FnOnce() -> String>(arg: String) -> F
  |                                                     - expected `F` because of return type
6 | {
7 |     || arg
  |     ^^^^^^ expected type parameter, found closure
  = note: expected type `F`
             found type `[closure@src/ 7:11 arg:_]`
  = help: type parameters must be constrained to match other types
  = note: for more information, visit

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Oh, never-mind, I figured it out. Here's what worked: (playground).

fn main() {
    dbg!(test_func(&mut String::from("test"))());

fn test_func(arg: &mut String) -> impl FnOnce() -> Result<(), ()> + '_
    move || {
        println!("{}", arg);

The above example was actually a little to simple because in my actual use-case I needed to capture a mutable reference to a struct use it in the body, and return a result.

Edit: Oh, and FnOnce only needs to be an FnMut because I'm not taking ownership of arg.

In this case it could just be Fn because you aren't mutating anything from the environment.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.