borrowed value does not live long enough reference in a struct

Viewed 28

I am new to Rust and stumbled upon a problem that I cannot wrap my head around. I have a struct Customer that contains a vector of account references. The compiler suggested I should use the lifetime specifier 'a which as far as I understand means, that the accounts cannot be destroyed before the customer.

pub struct Account {
    pub balance: f32,
}

pub struct Customer<'a> {
    accounts: Vec<&'a mut Account>,
}

Now I want to implement a function that creates a new account for my customer, I assumed it could work something like this:

impl<'a> Customer<'a> {
    pub fn create_account(&mut self, balance: f32) {
        let mut account = Account{balance};
        self.accounts.push(&mut account);
    }
}

However I get an error:

error[E0597]: `account` does not live long enough
  --> src\banking\mod.rs:16:28
   |
8  | impl<'a> Customer<'a> {
   |      -- lifetime `'a` defined here
...
16 |         self.accounts.push(&mut account);
   |         -------------------^^^^^^^^^^^^-
   |         |                  |
   |         |                  borrowed value does not live long enough
   |         argument requires that `account` is borrowed for `'a`
17 |     }
   |     - `account` dropped here while still borrowed

I assume the reason is that the account variable gets destroyed at the end of the create_account function. However, how can I create a new account and assign it to the customer?

2 Answers

Your customers currently mutably borrow their accounts. Someone has to own that data. Since there's no other structures in the code that I can see, I assume you meant to have the customers own the data. If so, just get rid of the &mut.

pub struct Customer {
  accounts: Vec<Account>,
}

...

impl<'a> Customer<'a> {
  pub fn create_account(&mut self, balance: f32) {
    let account = Account { balance };
    self.accounts.push(account);
  }
}

As a bonus point, Customer no longer has lifetime arguments, it simply exists independently.

You are correctly identifying the cause of the compiler error. For how to fix it, you need to consider your design. Because your Customer type has a vector of references to Accounts, structurally you are implying that the accounts are owned by something else. For example, you could have a Bank type that actually stores and owns the Accounts, and then the Customer can have a reference. Alternatively, you could change your Customer type to own the Accounts, rather than references to Accounts.

Related