我需要一个捕获按值且最多被调用一次的闭包,但是我无法在每个传递的闭包上都使用闭包单态化的函数,因为闭包和函数是相互递归的,并且单态化阶段失败。我尝试了类似的东西:

fn closure_user(closure: Box<FnOnce(usize) -> bool>) -> bool {
    closure(3)
}

fn main() {
    let big_data = vec![1, 2, 3, 4];
    closure_user(Box::new(|x| {
        let _ = big_data.into_iter();
        false
    }));
}

error[E0161]: cannot move a value of type dyn std::ops::FnOnce(usize) -> bool: the size of dyn std::ops::FnOnce(usize) -> bool cannot be statically determined
 --> src/main.rs:2:5
  |
2 |     closure(3)
  |     ^^^^^^^

拆箱版本为:
fn closure_user<F>(closure: F) -> bool
where
    F: FnOnce(usize) -> bool,
{
    closure(42)
}

fn main() {
    let big_data = vec![1, 2, 3, 4];
    closure_user(|x| {
        let _ = big_data.into_iter();
        false
    });
}

似乎不可能将封闭盒作为FnOnce特征对象进行装箱和拆箱。有什么办法可以装箱(无类型参数)和按需移动(仅一个调用)?

最佳答案

有可能,但是现在您必须通过不稳定的 std::thunk::Thunk 来做到这一点:

use std::thunk::{Invoke, Thunk};

fn closure_user(closure: Thunk<usize, bool>) -> bool {
    closure.invoke(3)
}

fn main() {
    let big_data = vec![1, 2, 3, 4];
    closure_user(Thunk::with_arg(|x| {
        let _ = big_data.into_iter();
        false
    }));
}

这是由于当前类型系统上的限制-无法从特征对象中移出-应该尽快解决。有关更多信息,请参阅博客文章Purging Proc

关于closures - 有什么办法可以装盒装和按装扣子吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28645624/

10-13 00:45