This isn't a help request, but rather the result of figuring out the answer myself after hours of searching with no answer to this specific question. Maybe this can help people in the future (heh).
The Problem
So I am working my way through a little project and wanted to use async / tokio. So far a lot of stuff is working great, however I don't understand how await is working in some cases.
The most common example being listening TCP, I see no Future implementation
TcpListener
accept
method returns TcpStream
type. I would expect to see a Future
implementation listed in both of these pages, however there is none, yet I can still obviously use await and it works fine.
However, for Sleep
, there it is, but it also works the same way.
It is even more odd that when I run these tests, I get unexpected results
use tokio::net::TcpListener;
fn main() -> () {
TcpListener::bind("127.0.0.1:8080").hgfjk();
}
use tokio::net::TcpListener;
#[tokio::main]
async fn main() -> () {
TcpListener::bind("127.0.0.1:8080").hgfjk();
}
Both give the same error
error[E0599]: no method named `hgfjk` found for opaque type `impl Future<Output = Result<tokio::net::TcpListener, std::io::Error>>` in the current scope
--> src/lib.rs:5:41
|
5 | TcpListener::bind("127.0.0.1:8080").hgfjk();
|
I also checked out async-std and mio, and many of their types also lack a Future implementation.
I know await isn't really a method, but how is it working exactly if there isn't Future for all types?
The Answer
Note the function signatures and the async
keyword.
For TcpListener
we have this method
pub async fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener>
The async
keyword causes return type to be transformed as follows:
impl Future<Output = Result<tokio::net::TcpListener, std::io::Error>>
Why we could find Future
trait for Sleep
? Because Future
was implemented for Sleep
some reason I don't know and is beyond the scope of the document.
tokio::time::sleep
is a function that returns a Sleep
.
Here is the function signature. Note the lack of the async
keyword.
pub fn sleep(duration: Duration) -> Sleep
Hope this helps someone in the future. If anyone has anything to add, feel free.