简体   繁体   中英

Return a closure returning the function argument in Rust

I'm trying to a write a function, which will take an argument of type T and return a closure, which, when called, will return that argument. How do I write that?

pub struct ParseError {}

pub type Parser<T> = Box<dyn Fn(&str) -> Result<(&str, T), ParseError>>;

pub fn pure<T: 'static>(value: T) -> Parser<T> {
    Box::new(move |input: &str| -> Result<(&str, T), ParseError> { Ok((input, value)) })
}

The error:

    Checking parsec v0.1.0 (/home/arjaz/Documents/code/rust/parsec)
error[E0507]: cannot move out of `value`, a captured variable in an `Fn` closure
  --> src/parsec.rs:16:79
   |
12 | pub fn pure<T: 'static>(value: T) -> Parser<T>
   |                         ----- captured outer variable
...
16 |     Box::new(move |input: &str| -> Result<(&str, T), ParseError> { Ok((input, value)) })
   |                                                                               ^^^^^ move occurs because `value` has type `T`, which does not implement the `Copy` trait

error: aborting due to previous error

For more information about this error, try `rustc --explain E0507`.
error: could not compile `parsec`.

Here is a simplified version in the Rust playground , one that avoids Box and Parser. The function consumes value , and returns a closure that, when called, simply returns value . Note that the closure is of type FnOnce (or, more precisely, is of some type based on FnOnce ), so we can only call it once. After the call, the memory associated with value belongs to the caller.

If instead we use Fn , then the closure can be called multiple times. But after the first call, the closure no longer owns value -- it was given to the first caller as the return value -- so calling the closure a second time is not going to work. Hence the error. If a closure is going to return the value multiple times, then it must return a copy or clone of value , retaining ownership of the original for itself. Since the function is generic over the type of value , T , you would need to constrain T to be Copy or Clone .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM