假设我有一个如下所示的函数,它可能会失败.该函数也是异步的
async fn can_fail() -> Result<i32, Box<dyn std::error::Error>> {
let mut rng = rand::thread_rng();
let random: u8 = rng.gen();
if random % 2u8 == 0 {
Ok(42)
} else {
Err("error".to_string().into())
}
}
现在我想实现一个retry
函数,该函数可用于重试像can_fail
这样的函数.
我在try 的时候想到了这一点
fn retry<F: Fn() -> Result<i32, Box<dyn std::error::Error>>>(f: F, retries: i32) -> Result<i32, Box<dyn std::error::Error>>
{
let mut count = 0;
loop {
let result = f();
if result.is_ok() {
break result;
} else {
if count > retries {
break result
}
count += 1;
}
}
}
然后,在我try 使用时,我试图像这样将can_fail
放入闭合
let my_closure: Box<dyn Fn() -> Result<i32, Box<dyn std::error::Error>>> = Box::new(|| {
can_fail().await
});
但此操作失败,并显示错误
error[E0728]: `await` is only allowed inside `async` functions and blocks
--> src/main.rs:208:19
|
207 | let my_closure: Box<dyn Fn() -> Result<i32, Box<dyn std::error::Error>>> = Box::new(|| {
| -- this is not `async`
208 | can_fail().await
| ^^^^^^ only allowed inside `async` functions and blocks
所以我有点被困住了.所以我的问题是:
- 我想出的
retry
个能胜任这项工作吗?我不能说,因为我甚至不能结束它 - 如何修复此场景中的100 is only allowed inside 101 functions and blocks`错误?
- 还有,有没有可能让重试变得更通用?开始时,我对要返回的函数的返回类型进行了硬编码.在现实生活中,我希望它是通用的.如何才能做到这一点?