vessd
vessd

Reputation: 215

Why can't I make a reference to memory inside "if"?

I could make a copy of this vector, but that will take time and memory. I could write another println, but this is just an example — instead of println there may be several loops — and it will take space and complicate the code. I could perform the conversion in main and write two versions of the function call, but changing the reference is much easier.

fn foo(mut a: &Vec<i32>) {
    let mut c: Vec<i32>;

    if a[0] == 0 {
        c = vec![1; 3];
        a = &c;
    }

    println!("{:?}", a);
}

fn main() {
    let a: Vec<i32> = vec![0; 3];
    foo(&a);
}

Error:

main.rs:9:14: 9:15 error: `c` does not live long enough
main.rs:9         a = &c;
                       ^

Upvotes: 0

Views: 126

Answers (1)

Levans
Levans

Reputation: 15022

The rules of lifetime in rust are quite (very) strict: if you have a reference to an object, this object must live longer than the reference, in both direction.

This means the reference must be created after the object.

In your case, a exists before c, so the assignment a = &c is invalid. A simple fix can be to create a copy of the reference after c is created and work on this copy:

fn foo(vec_ref: &Vec<i32>){

    let mut c: Vec<i32>;
    let mut a = vec_ref

    if a[0] == 0 {
        c = vec![1; 3];
        a = &c;
    }
    println!("{:?}",a);
}

or in a more rusty way:

fn foo(vec_ref: &Vec<i32>){

    let mut c: Vec<i32>;
    let a = if vec_ref[0] == 0 {
        c = vec![1; 3];
        &c
    } else {
        vec_ref
    };
    println!("{:?}",a);
}

Upvotes: 2

Related Questions