将局部变量复制到 Rust 中的向量中

问题描述

我是 Rust 的新手,我正在尝试将局部变量复制到向量中。这是我的尝试:

#[derive(copy,Clone)]
struct DFAItem<'a> {
    reading: usize,production: &'a grammar::CFGProduction<'a>,next_terminal: i32,}

fn add_nonterminal<'a>(cfg: &'a grammar::CFG,nonterminal: usize,itemset: &'a mut Vec<DFAItem>) {
    let productions = &cfg.productions[nonterminal];
    for prod in productions {
        let item = DFAItem {
            reading: 0,production: prod,next_terminal: 0,};
        itemset.push(item); //here,I get a lifetime error (lifetime 'a required).
        match prod.rhs[0] {
            grammar::Symbol::Nonterminal(x) if x != nonterminal => add_nonterminal(cfg,x,itemset),_ => (),}
    }
}

我知道我无法修改 item 的生命周期以使其与 itemset 匹配,所以我要做的是将 item 复制到向量中,这样就有了向量的生命周期。任何帮助/提示将不胜感激。

此外,有人知道语法,以便我可以将 cfg 更改为至少与项集一样长的生命周期而不是相同吗?我会直接宣布第二次生命,还是有更好的方法来做到这一点?

编辑:这里是 CFG 和 CFGProduction 的定义:

pub enum Symbol {
    Terminal(i32),Nonterminal(usize),}

pub struct CFGProduction<'a> {
    pub nonterminal: usize,pub rhs: &'a Vec<Symbol>,}

pub struct CFG<'a> {
    pub terminals: Vec<i32>,pub productions: Vec<Vec<CFGProduction<'a>>>,}

解决方法

首先,itemset vec 的生命周期无关紧要,不需要受任何限制。其次,CFGDFAItem 具有通用的生命周期参数,因此在函数参数中使用它们时应如此说明。

这是我的看法,这里涉及两个重要的生命周期:

  • 'aCFGProduction 所需的生命周期
  • 'bcfg 的生命周期及其存储在 DFAItems 中的后续引用

因此,DFAItem 应该有两个生命周期:

struct DFAItem<'a,'b> {
    // ...
    production: &'b grammar::CFGProduction<'a>,// ...
}

add_nonterminal() 的签名如下所示:

fn add_nonterminal<'a,'b>(cfg: &'b grammar::CFG<'a>,nonterminal: usize,itemset: &mut Vec<DFAItem<'a,'b>>) {
    // ...
}

随着这些生命周期的变化,函数体按原样编译。在 playground 上查看。


您可以选择来执行此操作,只需使用 'a 即可:

struct DFAItem<'a> {
    // ...
    production: &'a grammar::CFGProduction<'a>,// ...
}

fn add_nonterminal<'a>(cfg: &'a grammar::CFG<'a>,itemset: &mut Vec<DFAItem<'a>>) {
    // ...
}

但我建议不要这样做。具有模式 &'a Type<'a> 的类型,其中泛型生命周期与其自身相关联可能会导致问题;尤其是可变性。