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?

1

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

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: You should post a new question. Remember that Stack Overflow is not a discussion forum. :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.