Can anyone please shed some light on why this piece of code works?

Hello everyone

following my previous post stuck with lifetimes! again and the replies posted by members (thanks a lot) i did get to this piece of code to work.

use std::net::SocketAddr;
use std::io;

use tokio::io::BufReader;
use tokio::io::AsyncBufReadExt;
use tokio::io::AsyncWriteExt;
use tokio::net::tcp::ReadHalf;
use tokio::net::tcp::WriteHalf;

#[derive(Debug)]
pub struct User<'a> {
    reader: BufReader<ReadHalf<'a>>,
    writer: WriteHalf<'a>,
    addr: SocketAddr,
    username: String,
}

impl<'a> User<'a> {
    pub fn new(reader: ReadHalf<'a>, writer: WriteHalf<'a>, addr: SocketAddr) -> Self {
        let reader = BufReader::new(reader);

        Self {
            reader,
            writer,
            addr,
            username: String::new(),
        }
    }

    pub async fn ask<T: AsRef<str>>(&mut self, quest: T) -> io::Result<usize> {
        self.writer.write_all(quest.as_ref().as_bytes()).await.unwrap();
        self.reader.read_line(&mut self.username).await
    }
}

AFAIK the line let reader = BufReader::new(reader) will return an instance of BufReader which will be droped at the end of fn new function, so why the code runs when i return this instance in Self?

reader isn't dropped at the end of new, because it's moved to Self struct. And Self isn't dropped, because it's returned (moved to the caller).

Data held in variables is dropped only if it's not been moved elsewhere.

1 Like