0

I am trying to conditionally update an argument to a function:

struct A {
    foo: i32,
    bar: i32,
}

impl A {
    fn foobar<'a>(&'a self) {
        let a;
        if true { // something more complex obviously
            let x = A {
                foo: self.foo,
                bar: self.bar,
            };
            a = &x;
        } else {
            a = self;
        }
        
        println!("{} {}", a.foo, a.bar);
    }
}

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=27fcba42d135da6282bd000fd8e3db5d

Here, the function foobar receives an argument of type &A. Depending on some condition I want to replace this argument with another value of type &A.

I do understand why the above code results in the error 'x' does not live long enough. My question is whether there is a pattern to conditionally update the value of the argument a without requiring it to be mutable? Is there maybe a way to forcefully extend the lifetime of x?

heroxav
  • 1,387
  • 1
  • 22
  • 65

1 Answers1

1

Inside your if condition, you give to a a reference to x, which will be destroyed just after. Then a will hold a reference to a destroyed object.

You can fix it by declaring the x variable before the condition:

struct A {
    foo: i32,
    bar: i32,
}

impl A {
    fn foobar<'a>(&'a self) {
        let a;
        let x;
        if true { // something more complex obviously
            x = A {
                foo: self.foo,
                bar: self.bar,
            };
            a = &x;
        } else {
            a = self;
        }

        println!("{} {}", a.foo, a.bar);
    }
}

You can also simplify your code, by removing the lifetimes and using the pattern let a = if ... {} else {}; :

    fn foobar(&self) {
        let x;
        let a = if true { // something more complex obviously
            x = A {
                foo: self.foo,
                bar: self.bar,
            };
            &x
        } else {
            self
        };

        println!("{} {}", a.foo, a.bar);
    }
yolenoyer
  • 8,797
  • 2
  • 27
  • 61