问题描述
我是 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 的生命周期无关紧要,不需要受任何限制。其次,CFG
和 DFAItem
具有通用的生命周期参数,因此在函数参数中使用它们时应如此说明。
这是我的看法,这里涉及两个重要的生命周期:
-
'a
:CFGProduction
所需的生命周期 -
'b
:cfg
的生命周期及其存储在DFAItem
s 中的后续引用
因此,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>
的类型,其中泛型生命周期与其自身相关联可能会导致问题;尤其是可变性。