Значения не живут достаточно долго в конструкторе и установщике в OOP Rust - PullRequest
0 голосов
/ 04 сентября 2018

У меня есть следующий код:

//! # Messages

/// Represents a simple text message.
pub struct SimpleMessage<'a> {
    pub user: &'a str,
    pub content: &'a str,
}

impl<'a> SimpleMessage<'a> {

    /// Creates a new SimpleMessage.
    fn new_msg(u: &'a str, c: &'a str) -> SimpleMessage<'a> {
        SimpleMessage { user: u,
                        content: &c.to_string(), }
    }

    /// Sets a User in a Message.
    pub fn set_user(&mut self, u: User<'a>){
        self.user = &u;
    }
}

Но $ cargo run возвращает:

error[E0597]: borrowed value does not live long enough
  --> src/messages.rs:34:35
   | 
34 |                         content: &c.to_string(), }
   |                                   ^^^^^^^^^^^^^ temporary value does not live long enough
35 |     }
   |     - temporary value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 28:1...
   |
28 | impl<'a> SimpleMessage<'a> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0597]: `u` does not live long enough
   |
54 |         self.user = &u;
   |                      ^ borrowed value does not live long enough
55 |     }
   |     - borrowed value only lives until here
   |
note: borrowed value must be valid for the lifetime 'a as defined on the impl at 28:1...
  --> src/messages.rs:28:1
   |
28 | impl<'a> SimpleMessage<'a> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^

Я пытался изменить формат заимствования переменных в сигнатуре функции, и его содержимое не увенчалось успехом, это не кажется проблемой заимствования, но я не совсем понимаю это, как время жизни <'a> определенный в pub struct SimpleMessage<'a> четко обозначает самый длинный срок службы его компонентов, а impl<'a> SimpleMessage<'a> использует тот же срок службы.

Чего мне не хватает?

Аналогичный вопрос: «заимствованная стоимость не живет достаточно долго» при использовании шаблона строителя Не помогает решить эту проблему.

Ответы [ 2 ]

0 голосов
/ 04 сентября 2018

str.to_string() создаст принадлежащий *1003* String, который не будет жить дольше, чем метод new_msg, поэтому вы не сможете нигде передать его часть. Вместо этого просто используйте аргумент &str, так как он действителен в течение жизни 'a, что вам и нужно.

/// Creates a new SimpleMessage.
fn new_msg(u: &'a User, c: &'a str) -> SimpleMessage<'a> {
    SimpleMessage { user: u, content: c, }
}

Другой метод также имеет проблему. Вы пытаетесь указать собственный User, но структура SimpleMessage требует ссылки. Это должно выглядеть так:

/// Sets a User in a Message.
pub fn set_user(&mut self, u: &'a User<'a>){
    self.user = u;
}
0 голосов
/ 04 сентября 2018

Вам не нужно to_string, если вы хотите сохранить ссылку на строку. Кроме того, set_user также должен принимать ссылку, а не значение (потому что в структуре нет поля для его хранения):

pub struct User<'a> {
    pub data: &'a u8,
}

/// Represents a simple text message.
pub struct SimpleMessage<'a> {
    pub user: &'a User<'a>,
    pub content: &'a str,
}

impl<'a> SimpleMessage<'a> {
    fn new_msg(user: &'a User, content: &'a str) -> SimpleMessage<'a> {
        SimpleMessage { user, content }
    }

    pub fn set_user(&mut self, user: &'a User<'a>) {
        self.user = user;
    }
}

fn main() {
    let data1 = 1;
    let data2 = 2;
    let user1 = User { data: &data1 };
    let user2 = User { data: &data2 };
    let mut msg = SimpleMessage::new_msg(&user1, "test");
    msg.set_user(&user2);
}

Игровая площадка


Если вы хотите сохранить строки, созданные во время выполнения (например, с помощью вызова format!()), вы можете сохранить String:

pub struct SimpleMessage<'a> {
    pub user: &'a User<'a>,
    pub content: String,
}

. . . 

fn new_msg(user: &'a User, content: String) -> SimpleMessage<'a> {
    SimpleMessage { user, content }
}

. . . 

let mut msg = SimpleMessage::new_msg(&user1, format!("created at {}", "runtime"));

Детская площадка

...