I've been trying to understand and play with futures
(version 0.3) but couldn't make this work. As I understand, a function is able to return a future of type A
only if the type A
implements the future trait. If I create a struct and implement the future trait, it's okay but why String
doesn't work?
use futures::prelude::*;
async fn future_test() -> impl Future<Output=String> {
return "test".to_string();
}
I get the error:
the trait bound `std::string::String: core::future::future::Future` is not satisfied
the trait `core::future::future::Future` is not implemented for `std::string::String`
note: the return type of a function must have a statically known sizerustc(E0277)
So I told myself, okay then I can use Box
like:
async fn future_test() -> impl Future<Output=Box<String>> {
return Box::new("test".to_string());
}
But the error is same:
the trait bound `std::string::String: core::future::future::Future` is not satisfied
the trait `core::future::future::Future` is not implemented for `std::string::String`
note: the return type of a function must have a statically known sizerustc(E0277)
What am I doing wrong? And why does the future hold the String
instead of the Box
itself?
When a function is declared async
, it implicitly returns a future, with the return type of the function as its Output
type. So you would write this function:
async fn future_test() -> String {
"test".to_string()
}
Alternatively, if you wanted to explicitly specify return type as a Future
, you would drop the async
keyword. If you did that you would also need to construct a future to return, and you would not be able to use await
inside the function.
fn future_test2() -> impl Future<Output=String> {
ready("test2".to_string())
}
Note that futures::ready
constructs a Future that is immediately ready, which is appropriate in this case since there is no actual asynchronous activity going on in this function.