我试图将一系列解析为 token 树,但是当我尝试实现解析特征时,出现了与引用生存期相关的错误。我认为创建盒装版本会解决引用计数或生存期方面的任何问题。代码如下。

impl Parse for TokenTree {
    fn parse(&mut self) -> Tree {
        match self.clone() {
            TtDelimited(_, y) => {
                let mut y2 = box (*y).clone();
                match y2.delim {
                    token::DelimToken::Paren => y2.parse(),
                    _ => panic!("not done yet"),
                }
            }
            TtToken(_, t) => E(t),
            _ => panic!("not done yet"),
        }
    }
}

我得到的错误使问题很清楚,但是我找不到解决此特定问题的任何信息。
35:51 error: `*y2` does not live long enough
                     token::DelimToken::Paren => y2.parse(),
                                                       ^~
42:6 note: reference must be valid for the anonymous lifetime #1 defined on the block at 30:31...
 fn parse(&mut self) -> Tree{
     match self.clone(){
         TtDelimited(_, y) => {
             let mut y2 = box () (*y).clone();
             match y2.delim{
                 token::DelimToken::Paren => y2.parse(),
       ...
 38:14 note: ...but borrowed value is only valid for the block at 32:33
         TtDelimited(_, y) => {
             let mut y2 = box () (*y).clone();
             match y2.delim{
                 token::DelimToken::Paren => y2.parse(),
                 _ => panic!("not done yet"),
             }

最佳答案

在此代码中:

{
    let mut y2 = box (*y).clone();
    match y2.delim {
        token::DelimToken::Paren => y2.parse(),
        _ => panic!("not done yet"),
    }
}

您创建y2,它将仅在该块退出之前有效。您没有包括特征,但是我的猜测是parse返回对对象本身的引用,例如:
fn parse(&self) -> &str

引用只能与对象一样长,否则将指向无效数据。

编辑:怎么可能,可能如何工作

您必须跟踪要标记的字符串的生存期,并将标记的生存期与该输入相关联:

enum Token<'a> {
  Identifier(&'a str),
  Whitespace(&'a str),
}

trait Parser {
    // Important! The lifetime of the output is tied to the parameter `input`,
    // *not* to the structure that implements this!
    fn parse<'a>(&self, input: &'a str) -> Token<'a>;
}

struct BasicParser;

impl Parser for BasicParser {
    fn parse<'a>(&self, input: &'a str) -> Token<'a> {
        Token::Identifier(input)
    }
}

10-05 18:22