4

次のような単純な構造体が与えられます。

struct Server {
  clients: HashMap<usize, Client>
}

Clientとしてアクセスする最良の方法は何&mutですか? 次のコードを検討してください。

use std::collections::HashMap;

struct Client {
  pub poked: bool
}

impl Client {
  pub fn poked(&self) -> bool {
    self.poked
  }

  pub fn set_poked(&mut self) {
    self.poked = true;
  }
}

struct Server {
  clients: HashMap<usize, Client>
}

impl Server {
  pub fn poke_client(&mut self, token: usize) {
    let client = self.clients.get_mut(&token).unwrap();
    self.poke(client);
  }

  fn poke(&self, c: &mut Client) {
    c.set_poked();
  }
}

fn main() {
    let mut s = Server { clients: HashMap::new() };
    s.clients.insert(1, Client { poked: false });

    s.poke_client(1);

    assert!(s.clients.get(&1).unwrap().poked() == true);
}

私が見る唯一の 2 つのオプションは、Client 内部でRefCell/を使用することです。Cell

pub struct Client {
    nickname: RefCell<Option<String>>,
    username: RefCell<Option<String>>,
    realname: RefCell<Option<String>>,
    hostname: RefCell<Option<String>>,
    out_socket: RefCell<Box<Write>>,
}

または、 をラップするclientsRefCell、 に対して次のような単純なメソッドを作成できなくなりますServer

pub fn client_by_token(&self, token: usize) -> Option<&Client> {
    self.clients_tok.get(&token)
}

クロージャーの使用を強制します(例with_client_by_token(|c| ...))。

4

1 に答える 1