2015-01-23 2 views
0

У меня есть структура, назовите ее Master, у которой должно быть поле slaves, которое представляет собой коллекцию Slave. При добавлении к Master, каждый Slave должен быть отмечен уникальным идентификатором, назначенным ему Master.Как объявить и реализовать структуру, которая отслеживает коллекцию структур?

Так я пытаюсь сделать это в настоящее время, как так:

pub struct Master { 
    slaves: VecMap<Slave> 
} 

impl Master { 
    // omitted constructor 
    // fn get_unique_id(&self) -> usize {...} 

    pub fn add_slave(&mut self, slave: &mut Slave) { 
     let new_id = self.get_unique_id(); 
     slave.set_id(new_id); 
     self.slaves.insert(new_id, *slave); 
     // Previous line causes "cannot move out of borrowed content" error 
    } 

    pub fn get_slave(&self, id: usize) -> Option<&Slave> { 
     self.slaves.get(&id) 
    } 
} 

Как я должен объявить поле рабов (VecMap рефов или значений) и реализовать эти методы правильно?

+1

Dietrich Epp был прав на деньги с его теперь удаленным ответом, в частности, первым предложением. В нем просто отсутствовал 'mut' (' & mut self, mut slave: Slave'). Это даже не влияет на подпись функции (можно также опустить ее и написать 'let mut slave = slave;' как первую строку тела). Надеюсь, он это увидит и вернет ответ. – delnan

ответ

3

Контейнеры содержат значение. В этом случае вы принимаете ссылку (slave: &mut Slave), а затем пытаетесь выполнить , воруют владениеSlave внутри вашей функции. Это большой нет-нет, поскольку вызывающий объект этого метода не знал бы, что вы потребляли элемент.

Вместо этого отказаться от права собственности на ваш товар при добавлении его:

pub fn add_slave(&mut self, slave: Slave) { 
    let mut slave = slave; // let us mutate it, now that we own it 
    let new_id = self.get_unique_id(); 
    slave.set_id(new_id); 
    self.slaves.insert(new_id, slave); 
} 

Я предпочитаю, чтобы принять пункт (slave: Slave), а затем сделать его изменяемым в теле функции. Таким образом, вызывающим абонентам метода не нужно заботиться о деталях реализации. Вы также можете объявить аргумент mut slave: Slave, если это вас беспокоит.

Другой альтернативой было бы изменить структуру, чтобы удерживать &mut Slave элементов, но я предполагаю, что вы хотите первое решение.

Смежные вопросы