首页 > 解决方案 > 返回一个闭包,返回 Rust 中的函数参数

问题描述

我正在尝试编写一个函数,它将接受 T 类型的参数并返回一个闭包,当调用该闭包时,它将返回该参数。我该怎么写?

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)) })
}

错误:

    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`.

标签: rustlifetimeborrow-checker

解决方案


这是Rust 游乐场中的简化版本,它避免了 Box 和 Parser。该函数使用value,并返回一个闭包,当调用该闭包时,只需返回value。请注意,闭包是类型的FnOnce(或者,更准确地说,是基于 的某种类型FnOnce),所以我们只能调用它一次。调用后,与之关联的内存value属于调用者。

如果改为使用Fn,则可以多次调用闭包。但是在第一次调用之后,闭包不再拥有value——它被作为返回值提供给第一个调用者——所以第二次调用闭包是行不通的。因此错误。如果闭包要多次返回该值,则它必须返回 的副本或克隆value,并为自己保留原始的所有权。由于该函数对 , 的类型是通用的value,因此T您需要将其限制TCopyor Clone


推荐阅读