无法创建迭代器并绑定到局部变量

时间:2018-10-04 16:10:52

标签: rust

我正在Rust中实现一个基本的代码解析器。我想对语言的标记进行迭代。我的自定义迭代器结构将借用存储在另一个结构中的代码String。这是实现:

fn main() {
    let tokenizer = Tokenizer {
        code: String::from("foo + bar "),
    };
    let token_iter = tokenizer.tokens();
    let program = parse(Box::new(token_iter));
    println!("{:?}", program);
}

#[derive(Debug)]
enum Token {
    Symbol(&'static str),
    Identifier(String),
}

struct Tokenizer {
    code: String,
}

impl Tokenizer {
    fn tokens(&self) -> TokenIterator {
        TokenIterator::new(&self.code)
    }
}

struct TokenIterator<'a> {
    code: &'a str,
}

impl<'a> TokenIterator<'a> {
    fn new(code: &'a str) -> TokenIterator {
        TokenIterator { code: code.trim() }
    }
}

impl<'a> Iterator for TokenIterator<'a> {
    type Item = Token;

    fn next(&mut self) -> Option<Self::Item> {
        if self.code.len() == 0 {
            return None;
        }
        if self.code.starts_with("+") {
            self.code = &self.code[1..].trim_left();
            return Some(Token::Symbol("+"));
        }
        let first_char = self.code.chars().nth(0).unwrap();
        if first_char.is_alphabetic() || first_char == '_' {
            let mut ident = String::new();
            while self.code.chars().nth(0).unwrap().is_alphanumeric()
                || self.code.chars().nth(0).unwrap() == '_'
            {
                ident.push(self.code.chars().nth(0).unwrap());
                self.code = &self.code[1..];
            }
            self.code = self.code.trim_left();
            return Some(Token::Identifier(ident));
        }
        panic!("invalid syntax:\n{}", self.code)
    }
}

#[derive(Debug)]
struct Program {
    name: &'static str,
    tokens: Vec<Token>,
}

fn parse(tokens: Box<Iterator<Item = Token>>) -> Program {
    Program {
        tokens: tokens.collect(),
        name: "foo",
    }
}

编译器不允许我创建迭代器并将其绑定到变量。

error[E0597]: `tokenizer` does not live long enough
 --> src/main.rs:5:26
  |
5 |         let token_iter = tokenizer.tokens();
  |                          ^^^^^^^^^ borrowed value does not live long enough
...
8 |     }
  |     - borrowed value only lives until here
  |
  = note: borrowed value must be valid for the static lifetime...

为什么令牌生成器需要在'static生存期内生存?当我更改main函数以在循环中使用迭代器而不将其绑定到局部变量时,它将如何编译?这段代码出于某些原因起作用...

fn main() {
    let tokenizer = Tokenizer {
        code: String::from("foo + bar "),
    };
    for token in tokenizer.tokens() {
        println!("{:?}", token);
    }
}

0 个答案:

没有答案