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
,但traitFnOnce()
不接受任何参数。参数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))作为框
}));
}