i tried tokio with tasks but nothing is working can anyone tell me what is wrong with this code
fn main() {
block_on(speak());
}
async fn speak() {
let hold = vec![say(),greet()];
let results = join_all(hold).await;
}
async fn say(){
println!("hello");
}
async fn greet(){
println!("world");
}
here is the compiler output
error[E0308]: mismatched types
--> sync\src\main.rs:14:27
|
14 | let hold = vec![say(),greet()];
| ^^^^^^^ expected opaque type, found a different opaque type
...
23 | async fn greet(){
| - the Output of this async fn's found opaque type
|
= note: expected type impl core::future::future::Future (opaque type at <sync\src\main.rs:19:15>)
found opaque type impl core::future::future::Future (opaque type at <sync\src\main.rs:23:17>)
= note: distinct uses of impl Trait result in different opaque types
error: aborting due to previous error; 3 warnings emitted
For more information about this error, try rustc --explain E0308.
error: could not compile sync.
The two functions say and greet return two different types (two different futures), so you cannot store them in the same vector directly, as a vector may only contain a single type of future.
To get around this, you can box them: (in this case the type annotation is necessary)
use futures::future::BoxFuture;
use futures::future::join_all;
async fn speak() {
let hold: Vec<BoxFuture<_>> = vec![Box::pin(say()), Box::pin(greet())];
let results = join_all(hold).await;
}
Or you can use the join! macro: (only works with a fixed number of futures)
async fn speak() {
let results = tokio::join!(say(), greet());
}
Since there are only two of them, you can also use Either, which is cheaper than boxing them. Unlike join!, this allows having the same future many times (but still only two different types).
use futures::future::Either;
use futures::future::join_all;
async fn speak() {
let hold = vec![Either::Left(say()), Either::Right(greet())];
let results = join_all(hold).await;
}
Finally, you can also spawn them:
async fn speak() {
let hold = vec![
tokio::spawn(say()),
tokio::spawn(greet()),
];
for handle in hold {
handle.await.expect("Panic in spawned task");
}
}
In this case the tokio::spawn function makes the future start running immediately, so you don't also need join_all.