Search code examples
rustnulloption-type

How to set a field in a struct with an empty value?


I am writing a TCP client and have a conn field in my client struct. My client implements two methods new to instantiate the struct and connect to open a connection to the server and set that as the value of the conn field

pub struct FistClient {
    addr: String,
    conn: TcpStream,
}

impl FistClient {
    pub fn new(ip: &str, port: &str) -> Self {
        FistClient {
            addr: String::from(ip) + ":" + &String::from(port),
            // conn: <some-defaullt-value>,
        }
    }

    pub fn connect(&mut self, ip: &str, port: &str) {
        let res = TcpStream::connect(&self.addr);
        match res {
            Ok(c) => self.conn = c,
            Err(_) => panic!(),
        }
    }
}

I want to set the conn field in the new method to some default value. In Go I can do something like conn: nil but it doesn't work here. I tried Default::default() too but that trait isn't implemented for TCPStream how should I set it to a default value?


Solution

  • There's no null in Rust (and no Null Pointer Exception, Rust is designed for safety).

    You must either

    1) use an option (i.e. a field of type Option<TcpStream>)

    2) or better: return a result when building the struct

    Here, the best option would probably be to connect from inside a function returning a Result<FistClient>, so that you don't have to check whether your struct has a valid stream.

    I would do something like this:

    pub struct FistClient {
        addr: String,
        conn: TcpStream,
    }
    
    impl FistClient {
        pub fn new(ip: &str, port: &str) -> Result<Self> {
            let addr = format!("{}:{}", ip, port);
            let conn = TcpStream::connect(&addr)?;
            Ok(FistClient { addr, conn })
        }
    }
    

    Side note: It's really preferable to not build your applications with calls to panic, even when you think you're just building a dirty draft. Handle errors instead.