参数类型可能不够长

时间:2015-09-17 08:20:13

标签: rust

我有一个简单的程序,我试图实现多态帐户类型:

enum AccountType {
    INVALID,
    TYPE1,
    TYPE2,
}

trait Account {
    fn get_name(&self) -> String;
    fn get_type(&self) -> AccountType;
}

struct Accounts {
    accounts: Vec<Box<Account>>,
}

impl Accounts {
    fn new() -> Accounts {
        let accs: Vec<Box<Account>> = Vec::new();
        Accounts { accounts: accs }
    }

    fn add_account<A: Account>(&self, account: A) {
        self.accounts.push(Box::new(account));
    }
}

fn main() {
    let accounts = Accounts::new();
}

Rust Playground

编译时,我看到以下错误:

error[E0310]: the parameter type `A` may not live long enough
  --> src/main.rs:23:28
   |
22 |     fn add_account<A: Account>(&self, account: A) {
   |                    -- help: consider adding an explicit lifetime bound `A: 'static`...
23 |         self.accounts.push(Box::new(account));
   |                            ^^^^^^^^^^^^^^^^^
   |
note: ...so that the type `A` will meet its required lifetime bounds
  --> src/main.rs:23:28
   |
23 |         self.accounts.push(Box::new(account));
   |                            ^^^^^^^^^^^^^^^^^

我已尝试将生命周期添加到该类型但无法找到正确的方法。如果这不是在Rust中进行多态性的正确方法,请告诉我。

2 个答案:

答案 0 :(得分:8)

我会尝试提供更全面的答案:该问题与accounts Accounts成员的定义有关。此上下文中的Vec<Box<Account>>等同于Vec<Box<Account + 'static>>,即该框不能包含对堆栈上数据的任何引用。另一方面,add_account的声明不会限制类型的生命周期:它等同于fn add_account<'a, A: Account + 'a>(&self, account: A) {

解决方案是确保A型足够长。最简单的方法是只添加错误消息(A: 'static)中建议的fn add_account<A: Account + 'static>(&self, account: A) {绑定。

如果您不想复制帐户数据,可以执行更复杂的操作,例如:

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));
    }
}

但是,此时,您的数据结构可能比您实际需要的更为通用。

答案 1 :(得分:3)

编译器的建议确实有效。如果你按如下方式写add_account

fn add_account<A: Account + 'static>(&mut self, account: A) {
    self.accounts.push(Box::new(account));
}

你的代码编译。 (顺便提一下,您需要&mut self,而不是&self此处<)