【问题标题】:How to set a field in a struct with an empty value?如何在结构中设置一个空值的字段?
【发布时间】:2019-09-16 18:00:42
【问题描述】:

我正在编写一个 TCP 客户端,并且在我的客户端结构中有一个 conn 字段。我的客户端实现了两种方法new 来实例化结构并连接以打开与服务器的连接并将其设置为conn 字段的值

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!(),
        }
    }
}

我想将新方法中的conn 字段设置为某个默认值。在 Go 中,我可以执行 conn: nil 之类的操作,但在这里不起作用。我也尝试了Default::default(),但是TCPStream 没有实现该特征我应该如何将其设置为默认值?

【问题讨论】:

    标签: rust null optional


    【解决方案1】:

    Rust 中没有 null(也没有空指针异常,Rust 是为安全而设计的)。

    你必须要么

    1)使用option(即Option&lt;TcpStream&gt;类型的字段)

    2) 或更好:在构建结构时返回 result

    在这里,最好的选择可能是从返回 Result&lt;FistClient&gt; 的函数内部进行连接,这样您就不必检查您的结构是否有有效的流。

    我会这样做:

    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 })
        }
    }
    

    旁注:最好不要通过调用panic 来构建应用程序,即使您认为自己只是在构建脏草稿。 Handle errors 代替。

    【讨论】:

      【解决方案2】:

      在 Rust 中,null 的概念是用 Option 建模的。你给一个字段类型 Option&lt;TcpStream&gt; 表示它可能不存在 (None),或者是一个有效值 (Some(TcpStream))。

      pub struct FistClient {
          addr: String,
          conn: Option<TcpStream>,
      }
      
      impl FistClient {
          pub fn new(ip: &str, port: &str) -> Self {
              FistClient {
                  addr: String::from(ip) + ":" + &String::from(port),
                  conn: None,
              }
          }
      
          pub fn connect(&mut self, ip: &str, port: &str) {
              let res = TcpStream::connect(&self.addr);
              match res {
                  Ok(c) => self.conn = Some(c),
                  Err(_) => panic!(),
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        如果您想保留此调用模式,则需要将您的类型更改为 Option&lt;TCPStream&gt;Option 表示可能缺少具有两个枚举变体的值(即 null):Some(_)None

        一旦你有了这个,你可以很容易地通过调用as_mut来检索一个Option&lt;&amp;mut T&gt;来检索一个对内部成员的可变引用。

        【讨论】:

          猜你喜欢
          • 2021-11-01
          • 2022-01-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-11-21
          • 1970-01-01
          • 2021-01-26
          相关资源
          最近更新 更多