为什么File需要是可变的来调用Read :: read_to_string?

时间:2017-12-05 19:08:56

标签: file rust immutability

这是2nd edition Rust tutorial

中的一行
let mut f = File::open(filename).expect("file not found");

我假设文件描述符是一个基本上没有变化并且是只读的数字的包装器。

编译器抱怨该文件不能被可变地借用,并且我假设它是因为方法read_to_string将实例作为self参数作为可变,但是问题是"为什么" ?关于文件描述符有什么变化?是跟踪光标位置还是什么?

error[E0596]: cannot borrow immutable local variable `fdesc` as mutable
  --> main.rs:13:5
   |
11 |     let fdesc = File::open(fname).expect("file not found");
   |         ----- consider changing this to `mut fdesc`
12 |     let mut fdata = String::new();
13 |     fdesc.read_to_string(&mut fdata)
   |     ^^^^^ cannot borrow mutably

整个来源:

fn main() {
    let args: Vec<String> = env::args().collect();
    let query = &args[1];
    let fname = &args[2];
    println!("Searching for '{}' in file '{}'...", query, fname);

    let fdesc = File::open(fname).expect("file not found"); //not mut
    let mut fdata = String::new();
    fdesc.read_to_string(&mut fdata)
        .expect("something went wrong reading the file");

    println!("Found: \n{}", fdata);
}

1 个答案:

答案 0 :(得分:6)

  

我假设它是因为方法read_to_string将实例作为self参数作为可变

是的,这是正确的:

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

特征方法Read::read_to_string将接收器作为可变引用,因为通常,这是从某些东西实现“读取”所需要的。您将更改缓冲区或偏移量或某些内容

是的,实际的File 可能只包含基础文件描述符(例如在Linux或macOS上)或句柄(例如Windows)。在这些情况下,操作系统处理跨线程同步访问。但这甚至都没有保证 - 这取决于平台。像Redox这样的东西实际上可能在File的实现中有一个可变的引用。

如果Read特征不接受&mut self,则BufReader之类的类型必须使用内部可变性等内容,从而降低Rust引用的有用性。

另见: