Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 一次遍历整个文件一个字符_Rust_Lifetime - Fatal编程技术网

Rust 一次遍历整个文件一个字符

Rust 一次遍历整个文件一个字符,rust,lifetime,Rust,Lifetime,我对生锈是个新手,我正在与生命的概念作斗争。我想让一个每次遍历一个文件的结构成为一个字符,但我遇到了需要使用寿命的问题。我试着把它们添加到我认为应该添加的地方,但是编译器不高兴。这是我的密码: struct Advancer<'a> { line_iter: Lines<BufReader<File>>, char_iter: Chars<'a>, current: Option<char>, peek:

我对生锈是个新手,我正在与生命的概念作斗争。我想让一个每次遍历一个文件的结构成为一个字符,但我遇到了需要使用寿命的问题。我试着把它们添加到我认为应该添加的地方,但是编译器不高兴。这是我的密码:

struct Advancer<'a> {
    line_iter: Lines<BufReader<File>>,
    char_iter: Chars<'a>,
    current: Option<char>,
    peek: Option<char>,
}

impl<'a> Advancer<'a> {
    pub fn new(file: BufReader<File>) -> Result<Self, Error> {
        let mut line_iter = file.lines();
        if let Some(Ok(line)) = line_iter.next() {
            let char_iter = line.chars();

            let mut advancer = Advancer {
                line_iter,
                char_iter,
                current: None,
                peek: None,
            };

            // Prime the pump. Populate peek so the next call to advance returns the first char
            let _ = advancer.next();

            Ok(advancer)
        } else {
            Err(anyhow!("Failed reading an empty file."))
        }
    }

    pub fn next(&mut self) -> Option<char> {
        self.current = self.peek;
        if let Some(char) = self.char_iter.next() {
            self.peek = Some(char);
        } else {
            if let Some(Ok(line)) = self.line_iter.next() {
                self.char_iter = line.chars();
                self.peek = Some('\n');
            } else {
                self.peek = None;
            }
        }

        self.current
    }

    pub fn current(&self) -> Option<char> {
        self.current
    }

    pub fn peek(&self) -> Option<char> {
        self.peek
    }
}

fn main() -> Result<(), Error> {
    let file = File::open("input_file.txt")?;
    let file_buf = BufReader::new(file);
    let mut advancer = Advancer::new(file_buf)?;

    while let Some(char) = advancer.next() {
        print!("{}", char);
    }

    Ok(())
}
struct Advancer,
当前:选项,
peek:选项,
}
恳求{
pub fn new(文件:BufReader)->结果{
让mut line_iter=file.lines();
如果让Some(Ok(line))=line_iter.next(){
设char_iter=line.chars();
让mut advancer=advancer{
国际热核试验堆生产线,
查里特,
目前:无,
皮克:没有,
};
//填充peek,以便下一次调用advance返回第一个字符
让uz=advancer.next();
Ok(前置器)
}否则{
错误(无论如何)(“读取空文件失败。”)
}
}
pub fn next(&mut self)->选项{
self.current=self.peek;
如果让Some(char)=self.char\u iter.next(){
self.peek=Some(char);
}否则{
如果让Some(Ok(line))=self.line_iter.next(){
self.char_iter=line.chars();
self.peek=Some('\n');
}否则{
self.peek=无;
}
}
自流
}
发布fn当前和自身)->选项{
自流
}
pub fn peek(&self)->选项{
自我窥视
}
}
fn main()->结果{
让file=file::open(“input_file.txt”)?;
让file_buf=BufReader::new(文件);
让mut advancer=advancer::new(文件?)?;
而让Some(char)=advancer.next(){
打印!(“{}”,字符);
}
好(())
}
下面是编译器告诉我的:

error[E0515]: cannot return value referencing local variable `line`
  --> src/main.rs:37:13
   |
25 |             let char_iter = line.chars();
   |                             ---- `line` is borrowed here
...
37 |             Ok(advancer)
   |             ^^^^^^^^^^^^ returns a value referencing data owned by the current function

error[E0597]: `line` does not live long enough
  --> src/main.rs:49:34
   |
21 | impl<'a> Advancer<'a> {
   |      -- lifetime `'a` defined here
...
49 |                 self.char_iter = line.chars();
   |                 -----------------^^^^--------
   |                 |                |
   |                 |                borrowed value does not live long enough
   |                 assignment requires that `line` is borrowed for `'a`
50 |                 self.peek = Some('\n');
51 |             } else {
   |             - `line` dropped here while still borrowed

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0515, E0597.
For more information about an error, try `rustc --explain E0515`.
error: could not compile `advancer`.
错误[E0515]:无法返回引用局部变量'line'的值`
-->src/main.rs:37:13
|
25 |让char_iter=line.chars();
|---“line”在这里借用
...
37 |正常(提前器)
|^^^^^^^^^^^^^^^^返回一个值,该值引用当前函数拥有的数据
错误[E0597]:`line`的寿命不够长
-->src/main.rs:49:34
|
21 | impl{
|--此处定义的生存期“a”
...
49 | self.char_iter=line.chars();
|                 -----------------^^^^--------
|                 |                |
||借来的价值不够长久
|作业要求为“a”借用“line”`
50 | self.peek=Some('\n');
51 |}其他{
|-‘line’在这里还借着
错误:由于之前的两个错误而中止
有些错误有详细的解释:E0515、E0597。
有关错误的详细信息,请尝试“rustc--explain E0515”。
错误:无法编译“advancer”。
一些注意事项:

  • 从创建该字符串时使用的字符串。因此,在迭代器处于活动状态时,不能删除该字符串。但在
    new()
    方法中,当引用该字符串的迭代器存储在结构中时,拥有该字符串的
    变量将消失
  • 您也可以尝试将当前行存储在结构中,这样它就足够长了,但是–结构不能保存对自身的引用
  • 你能在一个不将引用存储到字符串中的字符串上生成一个字符迭代器吗?是的,可能,例如,通过将字符串中的当前位置存储为一个整数——它不应该是字符的索引,因为字符的长度可以超过一个字节,所以你需要自己处理底层字节(使用例如,从当前索引开始获取下一组字节,这些字节形成一个字符)
  • 有没有更简单的方法?是的,如果性能不是最重要的,一个解决方案是利用
    Vec
    的实例(它使用
    不安全的
    魔术来创建一个对象,该对象将自己的一部分交出来):
let char_iter=file_buf.lines().flat_map(| line_res |{
让line=line_res.unwrap_或(String::new());
line.chars().collect::()
});
请注意,仅返回
line.chars()
与第一点的问题相同


您可能认为该字符串应该有一个类似的
IntoIterator
实例,我也不反对。

为什么有
BufReader@nnnmmm我取出了借来的代码,但我的生命周期仍然存在问题。我用最新版本更新了代码。