2

Given the following code (which does not compile):

fn main() {
    let mut v = vec!();

    {
        let name = "Bob the Builder".to_string();

        v.push(&name);
    }

    for m in &v{
        println!("{}", m);
    }
}

I have created a variable binding to a Rust String type which will go out of scope within the first set of curly braces. Is there a way to somehow move the ownership of the String such that the vector itself owns it?

This is an arbitrary example however I'm just trying to understand if this concept is possible.

I already know that if I use a string literal this will be regarded as a static string which will exist for the lifetime of the entire app and therefore this code would compile but I'm just trying to understand if a collection in Rust can own data. I know Rust is not Objective-C but Objective-C has collections with the ability to retain their data.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Ralph Caraveo
  • 10,025
  • 7
  • 40
  • 52

1 Answers1

6

The vector will own it.. as long as you don't pass a reference to it.

Changing your code to this:

fn main() {
    let mut v = vec!();
    {
        let name = "Bob the Builder".to_string();

        v.push(name); // <--- no ampersand

        println!("{}", name); // <---- error, use of moved value
    }

    for m in &v {
        println!("{}", m);
    }
}

..throws an error because name is now owned by the Vector. If you allow for the fact that the Vector now owns the string.. your code compiles (by removing my println! call):

fn main() {
    let mut v = vec!();
    {
        let name = "Bob the Builder".to_string();

        v.push(name); // <--- no ampersand
    }

    for m in &v {
        println!("{}", m); // <--- works fine
    }
}

So your problem is that you're passing a reference to your string into the vector. Essentially, at the end of the block your name value will be dropped and your &name reference in the Vector could potentially point to invalid memory.. making v[0].something_here() potentially dangerous. So the compiler stops you. But, if you transfer ownership of the name variable into the vector (by not passing a reference.. but passing the whole thing) then Rust knows to clean the string up when it cleans the Vector up.

Simon Whitehead
  • 63,300
  • 9
  • 114
  • 138