I have a simple program where I am trying to implement a polymorphic account type:
enum AccountType {
INVALID,
TYPE1,
TYPE2,
}
trait Account {
The compiler's suggestion actually works. If you write add_account
as follows:
fn add_account<A: Account + 'static>(&mut self, account: A) {
self.accounts.push(Box::new(account));
}
your code compiles. (Incidentally, you need &mut self
, not &self
here)
I'll try to give a more thorough answer: the issue has to do with the definition of the accounts
member of Accounts
. Vec<Box<Account>>
in this context is equivalent to Vec<Box<Account + 'static>>
, i.e. the box can't contain any references to data on the stack. On the other hand, the declaration of add_account
doesn't restrict the lifetime of the type: it's equivalent to fn add_account<'a, A: Account + 'a>(&self, account: A) {
.
The solution is to make sure the type A lives long enough. The simplest approach is to just add the A: 'static
bound suggested in the error message (fn add_account<A: Account + 'static>(&self, account: A) {
).
If you don't want to copy the Account data, you can do something more complicated, like this:
struct Accounts<'a> {
accounts: Vec<&'a Account + 'a>
}
impl<'a> Accounts<'a> {
fn new() -> Accounts<'a> {
Accounts { accounts: Vec::new() }
}
fn add_account<A: Account + 'a>(&mut self, account: &'a A) {
self.accounts.push(Box::new(account));
}
}
At this point, though, you have a data structure which is probably more general than you actually need.