Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何编写接受闭包集合的函数?_Rust - Fatal编程技术网

Rust 如何编写接受闭包集合的函数?

Rust 如何编写接受闭包集合的函数?,rust,Rust,我正在尝试编写一个函数,它接受类型为Fn()->()的闭包集合,即每个闭包不接受任何参数,不返回任何内容(我希望它们实际上是FnOnce,以便将其所有环境移动到闭包对象中) 我尝试过很多方法(比如使用Box()>和使用&'static),但我就是不能让它工作 我在中创建了一个要点,大致说明我正在尝试做什么 以下是简化代码: fn run_all_tests<I>(tests: I) where I: IntoIterator<Item = Box<FnOnce()

我正在尝试编写一个函数,它接受类型为
Fn()->()
的闭包集合,即每个闭包不接受任何参数,不返回任何内容(我希望它们实际上是
FnOnce
,以便将其所有环境移动到闭包对象中)

我尝试过很多方法(比如使用
Box()>
和使用
&'static
),但我就是不能让它工作

我在中创建了一个要点,大致说明我正在尝试做什么

以下是简化代码:

fn run_all_tests<I>(tests: I)
where
    I: IntoIterator<Item = Box<FnOnce() -> ()>>,
{
}

fn main() {
    let examples = [1, 2, 3];

    run_all_tests(examples.iter().map(
        |ex| Box::new(move |ex| assert!(ex > 0)),
    ));
}
fn运行所有测试(测试:I)
哪里
I:输入迭代器>,
{
}
fn main(){
让示例=[1,2,3];
运行所有测试(examples.iter().map(
|ex | Box::新建(移动| ex |断言!(ex>0)),
));
}
错误:

error[E0271]:类型不匹配解析`::Output==std::boxed::Box`

=注:由于对`std::iter::Iterator`的impl中的`std::iter::Iterator`的要求,`std::iter::Map代码存在几个问题:

  • 盒式闭包接受一个参数
    ex
    ,但trait
    FnOnce()
    不接受任何参数。参数
    ex
    也会从外部闭包中隐藏参数
    ex
    ,因此我假设您的意思是内部闭包不带任何参数:
    move | | assert!(ex>0)

  • 由于将引用与非引用进行比较,
    ex>0
    中的类型不匹配。可以通过在模式匹配期间取消引用外部闭包参数来修复:
    |&ex|..

  • 类型推断不足以发现
    map
    返回的迭代器应该在
    Box
    之上,而不是
    Box
    之上。您可以添加显式转换来修复此问题:
    Box::new(move | | assert!(ex>0))as Box

  • 此时,代码将进行编译,但由于语言限制,当您添加对已装箱的
    FnOnce()
    的调用时,将出现编译错误。看见夜间生锈时,您可以将
    FnOnce
    更改为
    FnBox
    。否则,您可以使用
    FnMut
    ,或者使用该问题的解决方法之一。另一种解决方法是定义一个额外的特性(参见清单20-20和清单20-21)

  • 下面是使用
    FnBox
    的固定代码:

    #![feature(fnbox)]
    use std::boxed::FnBox;
    
    fn run_all_tests<I>(tests: I)
    where
        I: IntoIterator<Item = Box<FnBox()>>,
    {
        for t in tests {
            t();
        }
    }
    
    fn main() {
        let examples = [1, 2, 3];
    
        run_all_tests(examples.iter().map(|&ex| {
            Box::new(move || assert!(ex > 0)) as Box<FnBox()>
        }));
    }
    
    #![功能(fnbox)]
    使用std::boxed::FnBox;
    fn运行所有测试(测试:I)
    哪里
    I:迭代器,
    {
    测试中的t{
    t();
    }
    }
    fn main(){
    让示例=[1,2,3];
    运行所有测试(例如.iter().map(|&ex |){
    框::新建(移动| |断言!(ex>0))作为框
    }));
    }