0

I have this simple example:

fn make_string<'a>() -> &'a str {
    let s : &'static str = "test";
    s
}

fn make_str<'a>() -> &'a str {
    let s : String = String::from_str("test");
    s.as_slice()
}

fn main() {
    println!("{}", make_string());
    println!("{}", make_str());
}

Error message:

<anon>:8:9: 8:10 error: `s` does not live long enough
<anon>:8         s.as_slice()
                 ^
<anon>:6:34: 9:6 note: reference must be valid for the lifetime 'a as defined on the block at 6:33...
<anon>:6     fn make_str<'a>() -> &'a str {
<anon>:7         let s : String = String::from_str("test");
<anon>:8         s.as_slice()
<anon>:9     }
<anon>:6:34: 9:6 note: ...but borrowed value is only valid for the block at 6:33
<anon>:6     fn make_str<'a>() -> &'a str {
<anon>:7         let s : String = String::from_str("test");
<anon>:8         s.as_slice()
<anon>:9     }
error: aborting due to previous error
playpen: application terminated with error code 101
Program ended.

It seems that the borrow checker recognizes that 'static is a greater lifetime than 'a so the conversion for make_string works, but make_str fails. Is there a way to create a reference from String and extend it to lifetime 'a, since String is heap allocated?

noisecapella
  • 814
  • 7
  • 17
  • Possible duplicate of [Why can't I return an &str value generated from a String?](http://stackoverflow.com/questions/29781331/why-cant-i-return-an-str-value-generated-from-a-string) – malbarbo May 26 '16 at 22:12

1 Answers1

2

There is a fundamental misconception here: String is not heap allocated.

The content of String is heap allocated, but its lifetime is tied to the lifetime of the String object itself, and whenever String is dropped (here, at the end of make_str), then the content of String is dropped too.

Therefore, the compiler is right: the lifetime of the result String::as_slice is less than or equal to that of String and the lifetime of String ends with the function... thus you cannot return a reference to it.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
  • Related question, say I created a String within a method of an object and I wanted to both set the object's field and return the String. If I return the String it would transfer ownership, which is not allowed since the field has it too. Is there a way to do this without cloning the string? – noisecapella Dec 03 '14 at 19:48
  • @noisecapella: You should [post a new question](http://stackoverflow.com/questions/ask). Remember that Stack Overflow is not a discussion forum. :) – Francis Gagné Dec 04 '14 at 00:42