gpt4 book ai didi

rust - 我如何编写一个接受闭包集合的函数?

转载 作者:行者123 更新时间:2023-11-29 08:07:45 24 4
gpt4 key购买 nike

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

我已经尝试了很多东西(比如使用 Box<Fn() -> ()> 和使用 &'static )但我就是无法让它工作。

我在 Rust Playground 中创建了一个要点大致展示我正在尝试做的事情。

这是简化的代码:

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

错误:

error[E0271]: type mismatch resolving `<[closure@src/main.rs:11:9: 11:49] as std::ops::FnOnce<(&{integer},)>>::Output == std::boxed::Box<std::ops::FnOnce() + 'static>`
--> src/main.rs:10:5
|
10 | run_all_tests(examples.iter().map(
| ^^^^^^^^^^^^^ expected closure, found trait std::ops::FnOnce
|
= note: expected type `std::boxed::Box<[closure@src/main.rs:11:23: 11:48]>`
found type `std::boxed::Box<std::ops::FnOnce() + 'static>`
= note: required because of the requirements on the impl of `std::iter::Iterator` for `std::iter::Map<std::slice::Iter<'_, {integer}>, [closure@src/main.rs:11:9: 11:49]>`
= note: required by `run_all_tests`

最佳答案

代码有几个问题:

  1. 您的盒装闭包带有一个参数 ex ,但特征 FnOnce()不带参数。参数ex还隐藏参数 ex来自外部闭包,所以我假设你的意思是内部闭包不带参数:move || assert!(ex > 0) .

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

  3. 类型推断不够强大,无法发现 map 返回的迭代器应该结束了Box<FnOnce()>而不是 Box<unique closure object> .您可以添加显式转换来解决此问题:Box::new(move || assert!(ex > 0)) as Box<FnOnce()>

  4. 此时,代码将编译,但是当您添加对盒装 FnOnce() 的调用时,您将遇到编译错误。由于语言限制。参见 "cannot move a value of type FnOnce" when moving a boxed function .在夜间 Rust 上,您可以更改 FnOnceFnBox .否则,您可以使用 FnMut相反,或使用该问题的解决方法之一。还有另一种解决方法,基于给定 in the Rust book 定义额外特征(参见 list 20-20 和 list 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()>
}));
}

关于rust - 我如何编写一个接受闭包集合的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45398756/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com