参数类型可能不够长

rus*_*oue 3 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();
}
Run Code Online (Sandbox Code Playgroud)

(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));
   |                            ^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)

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

Eli*_*man 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));
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,在这一点上,您的数据结构可能比实际需要的更为通用.

  • 您能否详细说明一下在这种情况下,`Vec&lt;Box&lt;Account&gt;&gt; 相当于 Vec&lt;Box&lt;Account + 'static&gt;&gt;` 是什么意思?我的意思是,上面代码中的什么表示它等价于 `Vec&lt;Box&lt;Account + 'static&gt;&gt;` ? (2认同)
  • 每个特征对象都有一个关联的生存期。如果您未指定生存期,则编译器会使用一些简单规则进行推断。https://doc.rust-lang.org/book/second-edition/ch19-02-advanced-lifetimes.html#trait-object-lifetimes具有一般说明;https://github.com/rust-lang/rfcs/blob/8ee535b4fcc8bb22c121ad19a36414f1259397c0/text/0599-default-object-bound.md具有基本原理。 (2认同)