4

How to properly create a member Vec? What am I missing here?

struct PG {
    names: &mut Vec<String>,
}

impl PG {
    fn new() -> PG {
        PG { names: Vec::new() }
    }

    fn push(&self, s: String) {
        self.names.push(s);
    }
}

fn main() {
    let pg = PG::new();
    pg.push("John".to_string());
}

If I compile this code, I get:

error[E0106]: missing lifetime specifier
 --> src/main.rs:2:12
  |
2 |     names: &mut Vec<String>,
  |            ^ expected lifetime parameter

If I change the type of names to &'static mut Vec<String>, I get:

error[E0308]: mismatched types
 --> src/main.rs:7:21
  |
7 |         PG { names: Vec::new() }
  |                     ^^^^^^^^^^
  |                     |
  |                     expected mutable reference, found struct `std::vec::Vec`
  |                     help: consider mutably borrowing here: `&mut Vec::new()`
  |
  = note: expected type `&'static mut std::vec::Vec<std::string::String>`
             found type `std::vec::Vec<_>`

I know I can use parameterized lifetimes, but for some other reason I have to use static.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Paulo Lieuthier
  • 426
  • 7
  • 14
  • 1
    Maybe this help you http://stackoverflow.com/questions/36413364/as-i-can-make-the-vector-is-mutable-inside-struct#36720608 – Angel Angel Apr 19 '16 at 15:05

1 Answers1

10

You don't need any lifetimes or references here:

struct PG {
    names: Vec<String>,
}

impl PG {
    fn new() -> PG {
        PG { names: Vec::new() }
    }

    fn push(&mut self, s: String) {
        self.names.push(s);
    }
}

fn main() {
    let mut pg = PG::new();
    pg.push("John".to_string());
}

Your PG struct owns the vector - not a reference to it. This does require that you have a mutable self for the push method (because you are changing PG!). You also have to make the pg variable mutable.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • Great! I'm still confused, though. `pg` and `self` need to be mutable, but `names` doesn't? I thought I was changing `names`, not `pg`. I will study more, if I can find good material about that. Thank you! – Paulo Lieuthier Apr 02 '15 at 15:16
  • 1
    @paulolieuthier Structs are entirely mutable or not. By having `pg` mutable, you are *able* to call the method that requires a mutable self reference. **Every** field of `PG` is mutable within that method, including `names`. – Shepmaster Apr 02 '15 at 16:16