I have an async function A which receives another async function B as an argument. Inside the function A, I wish to call the function B two times, passing to it a mutable borrow to some value. But the compiler complains that at the time of the second call the value is still borrowed.
Why doesn't this work? Isn't the scope of the future supposed to end after the await? Then the borrow should finish, right? What am I missing here?
Here is a minimal "toy version" of my code:
use std::future::Future;
async fn do_thing_single_value<'a, 'b, F, Fut>(value: &'a mut String, f: F) -> i32
where
F: Fn(&'b mut String) -> Fut,
Fut: Future<Output = i32>,
'a: 'b,
{
let v1: i32 = f(value).await;
// Error here, is says value is already borrowed!
let v2: i32 = f(value).await;
v1 + v2
}
async fn do_thing_all_values<'a, F, Fut>(values: &'a mut Vec<String>, f: F) -> i32
where
F: Fn(&'a mut String) -> Fut,
Fut: Future<Output = i32>,
{
let mut total = 0;
for v in values.iter_mut() {
let result = do_thing_single_value(v, &f).await;
total += result;
}
total
}
async fn thing_to_do(v: &mut String) -> i32 {
v.make_ascii_uppercase();
v.chars()
.map(|c| if c.is_ascii_digit() { 1 } else { 0 })
.sum()
}
#[tokio::main]
async fn main() -> Result<(), ()> {
let mut values = vec![String::from("asdf"), String::from("1234")];
let result = do_thing_all_values(&mut values, thing_to_do).await;
println!("result={:?}", result);
Ok(())
}