std::io::BufReader 物件借用和引用的問題

linghuyichong發表於2019-12-30

此問題來自於Rust社群,連結地址:https://users.rust-lang.org/t/why-must-i-m...
在問題中,題主使用如下程式碼讀取檔案內容Ok:

//第一段程式碼
use std::io::{self,BufRead};
use std::fs::File;
fn main() -> std::result::Result<(), std::io::Error> {
    let filename = "test.bed";
    let fi = File::open(filename)?;
    let bedreader = io::BufReader::new(fi); //注意,bedreader不是mutable
    for line in bedreader.lines() {
        println!("{}", line?);
    }
    Ok(())
}

但是當換成如下程式碼後,出錯:

//第二段程式碼
use std::io::{self,BufRead};
use std::fs::File;
fn main() -> std::result::Result<(), std::io::Error> {
    let filename = "test.bed";
    let fi = File::open(filename)?;
    let bedreader = io::BufReader::new(fi); //注意,bedreader不是mutable
    let mut line = String::new();
    while bedreader.read_line(&mut line).unwrap() > 0 {//此處報錯
        println!("{}", line.trim_end());
        line.clear();
    }
    Ok(())
}

在第二段程式碼中,題主認為試用while迴圈讀取內容,line已經定義成mutable的了,不應該出錯。

對於第二段程式碼,進行如下修改後就能正確執行,如下:

//對第二段程式碼修正
use std::io::{self,BufRead};
use std::fs::File;
fn main() -> std::result::Result<(), std::io::Error> {
    let filename = "test.bed";
    let fi = File::open(filename)?;
    let mut bedreader = io::BufReader::new(fi); //注意,bedreader是mutable
    let mut line = String::new();
    while bedreader.read_line(&mut line).unwrap() > 0 {//此處不再報錯
        println!("{}", line.trim_end());
        line.clear();
    }
    Ok(())
}

在第一段程式碼中,在for迴圈中使用的是透過bedreader.lines()讀取每一行,而該方法的定義為:

fn lines(self) -> Lines<Self> 

而在第二段程式碼中使用的read_line,定義為:

fn read_line(&mut self, buf: &mut String) -> Result<usize>

因此,從兩個方法的定義可以看出,第一段程式碼不需要定義成mutable,第二段程式碼中需要定義成mutable。

本作品採用《CC 協議》,轉載必須註明作者和本文連結
令狐一衝

相關文章