我正在尝试创建一个词法分析器,该词法分析器使用itertools::PutBack
对String
中的字符进行迭代。我打算将推回迭代器存储在struct中,并为其委派方法,以便我可以按枚举对字符进行分类,然后将其传递给词法分析器核心(尚未编写)的状态机。>
借位检查员对我不满意。列表底部附近的方法ParserEventIterator::new
导致错误。如何定义生存期或借用期,以便可以对其进行编译?还是我应该使用什么Rustic数据结构设计?
最终,我希望这样做是为了实现适当的特征以使其成为适当的迭代器。 (Rust的新手。在此之前,我已经用28种语言编程,但是这使我很头疼。)
这是一个代码示例:
extern crate itertools;
use itertools::put_back;
use std::fmt::Display;
use std::fmt::Formatter;
use std::fmt::Result;
pub enum ParserEvent {
Letter(char),
Digit(char),
Other(char),
}
impl ParserEvent {
fn new(c: char) -> ParserEvent {
match c {
'a'...'z' | 'A'...'Z' => ParserEvent::Letter(c),
'0'...'9' => ParserEvent::Digit(c),
_ => ParserEvent::Other(c),
}
}
}
impl Display for ParserEvent {
fn fmt(&self, f: &mut Formatter) -> Result {
let mut _ctos = |c: char| write!(f, "{}", c.to_string());
match self {
ParserEvent::Letter(letter) => _ctos(*letter),
ParserEvent::Digit(digit) => _ctos(*digit),
ParserEvent::Other(o) => _ctos(*o),
}
}
}
// ParserEventIterator
// Elements ('e) must have lifetime longer than the iterator ('i).
pub struct ParserEventIterator<'i, 'e: 'i> {
char_iter: &'i mut itertools::PutBack<std::str::Chars<'e>>,
}
impl<'i, 'e: 'i> ParserEventIterator<'i, 'e> {
fn new(s: &'e std::string::String) -> ParserEventIterator<'i, 'e> {
// THIS NEXT LINE IS THE LINE WITH THE PROBLEM!!!
ParserEventIterator {
char_iter: &mut put_back(s.chars()),
}
}
fn put_back(&mut self, e: ParserEvent) -> () {
if let Some(c) = e.to_string().chars().next() {
self.char_iter.put_back(c);
}
}
}
impl<'i, 'e: 'i> Iterator for ParserEventIterator<'i, 'e> {
type Item = ParserEvent;
fn next(&mut self) -> Option<ParserEvent> {
match self.char_iter.next() {
Some(c) => Some(ParserEvent::new(c)),
None => None,
}
}
}
fn main() {
let mut _i = ParserEventIterator::new(&String::from("Hello World"));
}
error[E0515]: cannot return value referencing temporary value
--> src/main.rs:43:9
|
43 | / ParserEventIterator {
44 | | char_iter: &mut put_back(s.chars()),
| | ------------------- temporary value created here
45 | | }
| |_________^ returns a value referencing data owned by the current function
答案 0 :(得分:1)
好吧,编译器通过反映一个显而易见的问题,几乎可以告诉您解决方案:您不能拥有借用期限不足够长的借用文件,即借用文件指向的堆栈存储器后不存在的位置。功能已被破坏。
之所以会发生这种情况,是因为借用引用了在函数体内新创建的对象(在这种情况下为itertools::struct::PutBack
实例)。该实例以及所有对其引用的引用在函数末尾被销毁。因此,编译器阻止您使用所谓的悬挂指针。
因此,您应该移动 PutBack
实例到您的struct
:
// ...
pub struct ParserEventIterator<'e> {
char_iter: itertools::PutBack<std::str::Chars<'e>>
}
impl<'e> ParserEventIterator<'e> {
fn new(s: &'e std::string::String) -> ParserEventIterator<'e> {
ParserEventIterator { char_iter: put_back(s.chars()) }
}
// ...
}