0

I have the following code:

//! # 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;
    }
}

But $ cargo run returns:

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> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^

I've tried changing the borrowing format of the variables at the function signature and it's contents with no success, it doesn't seem as a borrowing issue, but I don't really understand it, as the lifetime <'a> defined at pub struct SimpleMessage<'a> clearly designates the longest lifetime to it's components, and the impl<'a> SimpleMessage<'a> uses the same lifetime.

What am I missing?

Similar Question: “borrowed value does not live long enough” when using the builder pattern Doesn't really help resolve this issue.

Dialvive
  • 356
  • 7
  • 19

2 Answers2

2

str.to_string() will create an owned String, which will not live longer than the new_msg method, so you will not be able to pass a slice of it anywhere. Instead, just use the &str argument, since it is valid for the lifetime 'a, which is what you need.

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

The other method also has a problem. You are trying to give an owned User, but the SimpleMessage struct requires a reference. It should look like this:

/// Sets a User in a Message.
pub fn set_user(&mut self, u: &'a User<'a>){
    self.user = u;
}
Peter Hall
  • 53,120
  • 14
  • 139
  • 204
0

You don't need to_string if you want to store a reference to a string. Also, set_user must also take a reference, not a value (because there's no field in the struct to store it):

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

Playground


If you want to save strings that are created at runtime (for example, with format!() call) you may want to store a 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"));

Playground

ozkriff
  • 1,269
  • 15
  • 23