'перемещение происходит, потому что значение имеет тип' Ошибка ржавчины - PullRequest
1 голос
/ 08 февраля 2020

Я изучаю Rust и не понимаю, в чем проблема следующего кода

pub enum BagEntryState {
    UNUSED, USED, REMOVED
}

impl PartialEq for BagEntryState {
    fn eq(&self, other: &Self) -> bool {
        self == other
    }
}

pub struct BagEntry< T: std::cmp::PartialEq + fmt::Display> {
    state : BagEntryState,
    value: T,
}

impl<'a, T: std::cmp::PartialEq + fmt::Display> BagEntry<T> {
    pub fn new(value: T) -> BagEntry< T> {
        BagEntry {
            value,
            state: BagEntryState::UNUSED,
        }
    }

    pub fn value(self)->T {
        self.value
    }
}

impl<'a, T: std::cmp::PartialEq + fmt::Display> PartialEq for BagEntry<T> {
    fn eq(&self, other: &Self) -> bool {
        self.value == other.value
    }
}

impl<T: std::cmp::PartialEq + fmt::Display> fmt::Display for BagEntry<T> {
    // This trait requires `fmt` with this exact signature.
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.value)
    }
}

use core::fmt;


fn main() {

    let my_bagentry = BagEntry::new(String::from("ciao"));
    //println!("{}", my_bagentry.value());
    let mut contVec : Vec<BagEntry<String>>=vec![];
    contVec.push(my_bagentry);
    println!("state ={}", contVec[0]);
    println!("state ={}", contVec[0].value());


}

Код не компилируется из-за ошибки:

54 |     println!("state ={}", contVec[0].value());
   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move occurs because value has type `BagEntry<std::string::String>`, which does not implement the `Copy` trait

Я предполагаю, что проблема в том, что с value()

я раскрываю структурное внутреннее значение, но я не могу понять, где проблема и как ее решить.

Моя цель состоит в том, чтобы BagEntry владел значением, но я хочу безопасно выставить его вне структуры

1 Ответ

2 голосов
/ 08 февраля 2020

В основном то, что происходит:

  pub fn value(self)->T {
      self.value
  }

Здесь -> T означает, что вы перемещаете поле структуры из структуры. Это хорошо, но вы больше не можете использовать свой объект. Вы можете проверить это - вы не можете вызвать ваш println!("{}", my_bagentry.value()); дважды подряд - после первого my_bagentry становится недействительным.

Если я правильно понимаю, вы хотите только одолжить ценность вне объекта. Для этого вам нужно изменить сигнатуру вашего метода на заимствование одного .

pub fn value(&self)-> &T {
    &self.value
}

Теперь вызов будет занимать только объект, и полученная ссылка будет иметь время жизни этого заимствования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...