0

I wanted create some data using a for loop. I used following to do that.

struct Message<'a> {
    msg: &'a str
}

fn loop_function<'a>() -> Vec<Message<'a>> {
    let mut result = vec![];
    for x in 0..10 {
        result.push(Message { msg: format!("{}", x).trim() });
    }
    result
}

fn main() {
    loop_function();
}

But when I try to compile this I get following error related to lifetime of x.

src/main.rs:8:33: 8:49 error: borrowed value does not live long enough
src/main.rs:8       result.push(Message { msg: format!("{}", x).trim() });
                                               ^~~~~~~~~~~~~~~~
src/main.rs:5:44: 11:2 note: reference must be valid for the lifetime 'a as defined on the block at 5:43...
src/main.rs:5 fn loop_function<'a>() -> Vec<Message<'a>> {
src/main.rs:6     let mut result = vec![];
src/main.rs:7     for x in 0..10 {
src/main.rs:8       result.push(Message { msg: format!("{}", x).trim() });
src/main.rs:9   }
src/main.rs:10     result
               ...
src/main.rs:8:6: 8:60 note: ...but borrowed value is only valid for the statement at 8:5
src/main.rs:8       result.push(Message { msg: format!("{}", x).trim() });
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/main.rs:8:6: 8:60 help: consider using a `let` binding to increase its lifetime
src/main.rs:8       result.push(Message { msg: format!("{}", x).trim() });
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

Is there a way to extend the lifetime x so that I can return the vector?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Chathurika Sandarenu
  • 1,368
  • 13
  • 25
  • I was initially thinking that compile error was due to I'm trying to return a struct from the method. But it seems like it was not the case, and error is due to the &str used inside struct. – Chathurika Sandarenu Apr 28 '15 at 16:07
  • No worries :) "Duplicate" questions are not inherently "bad" or anything (contrary to most other close reasons), it is just that redirecting all of them toward a single question helps concentrating the efforts in building great answers. – Matthieu M. Apr 28 '15 at 17:09

1 Answers1

1

I asked the same question recently. It can't be done. The answer in the link has an excellent explanation. My solution was to return a String:

struct Message {
    msg: String
}

fn loop_function() -> Vec<Message> {
    let mut result = vec![];
    for x in 0..10 {
        result.push(Message { msg: format!("{}", x).trim().to_string() });
    }
    result
}

fn main() {
    loop_function();
}
Community
  • 1
  • 1
anderspitman
  • 9,230
  • 10
  • 40
  • 61
  • While the answer and the example code are correct, I'd like to note that `x` is an integer and its string representation cannot possibly contain whitespace. Consequently, `trim()` is redundant, and you can just call `to_string()` on `x` directly: `Message { msg: x.to_string() }`. This way you save an extra allocation. – Vladimir Matveev Apr 25 '15 at 21:27
  • Good point, although I'm guessing (since OP is storing this in something called `Message`) that the actual code the OP is trying to make involves more than just integers. – anderspitman Apr 25 '15 at 22:39