WalzoneInterview Prep
📞 Interviewing soon? Practice with a realistic AI mock phone interview — it calls you, then scores you. First 15 min FREE →

Rust · Advanced · question 52 of 100

How do you implement async/await in Rust? Provide an example using the tokio runtime.?

📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

Async/await is used in Rust to write asynchronous code, making it easier to write and understand complex asynchronous code.

The Tokio runtime is a popular asynchronous runtime implementation in Rust, which makes it easy to write scalable and performant network applications. To implement async/await in Rust using Tokio, you need to first ensure that Tokio is included in your project’s dependencies in the ‘Cargo.toml‘ file. You can add the following to your ‘Cargo.toml‘ file:

    [dependencies]
    tokio = { version = "1.14", features = ["full"] }

Additionally, it is essential to import the necessary libraries, including the ‘async_trait‘ and ‘tokio‘ libraries. You can do that by including the following at the beginning of your Rust file:

    use tokio::net::TcpListener;
    use tokio::prelude::*;
    use tokio::stream::StreamExt;
    use tokio::sync::Mutex;
    use std::sync::Arc;

Once you have prepared the runtime environment, you can create an asynchronous function using the ‘async‘ keyword. An asynchronous function is one that returns a ‘Future‘. For example:

    async fn read_lines(filename: &str) -> Result<(), Box<dyn std::error::Error>> {
        let file = tokio::fs::read_to_string(filename).await?;
        for line in file.lines() {
            println!("{}", line);
        }
        Ok(())
    }

In this example, ‘tokio::fs::read_to_string‘ is an ‘async‘ function that you can await to read text from a file. Once the text is read, you can loop over the lines and print each line to the console.

You can also use ‘tokio::spawn‘ to run an asynchronous task on a separate thread, allowing the runtime to manage resources more efficiently. Here’s an example:

    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let listener = TcpListener::bind("127.0.0.1:8080").await?;
        let counter = Arc::new(Mutex::new(0));
        let mut incoming = listener.incoming();
        while let Some(stream) = incoming.next().await {
            let counter = counter.clone();
            tokio::spawn(async move {
                let mut stream = stream.unwrap();
                let mut buffer = [0u8; 1024];
                let n = stream.read(&mut buffer[..]).await.unwrap();
                let mut counter = counter.lock().await;
                *counter += 1;
                println!("{}: {}", *counter, std::str::from_utf8(&buffer[..n]).unwrap());
            });
        }
        Ok(())
    }

In this example, ‘TcpListener::bind‘ creates a new TCP listener and waits for incoming connections. When a client connects, we spawn a new asynchronous task with ‘tokio::spawn‘. This task reads data from the incoming client connection, increases a counter, and prints out the counter and the received data.

In summary, implementing async/await in Rust using the Tokio runtime involves importing necessary libraries, creating asynchronous functions using the ‘async‘ keyword, and using ‘tokio::spawn‘ to run asynchronous tasks on a separate thread.

Reading is step one. Saying it out loud is the interview. Our AI interviewer calls your phone and runs a realistic Rust interview — then scores it.
📞 Practice Rust — free 15 min
📕 Buy this interview preparation book: 100 Rust questions & answers — PDF + EPUB for $5

All 100 Rust questions · All topics