繁体   English   中英

Rust:为什么我会收到错误 [E0507]:无法移出共享引用后面的“files.input_file”

[英]Rust: why do I get error [E0507]: cannot move out of `files.input_file` which is behind a shared reference

我已将现实生活中的 Rust 代码缩小为以下内容:

use std::fs::File;
use std::io::{BufRead, BufReader};

struct FileHandler {
    input_file: File,
}

impl FileHandler {
    fn setup(in_file_name: &str) -> Self {
        let i_file = File::open(in_file_name).unwrap();
        Self { input_file: i_file }
    }
}

fn process_file(files: &FileHandler) {
    let lines = BufReader::new(files.input_file).lines();
    for _ln in lines {
        println!("one more line");
    }
}

fn main() {
    let files = FileHandler::setup("foo.txt");
    process_file(&files);
}

它不编译消息:

cannot move out of `files.input_file` which is behind a shared reference
  --> demo.rs:16:32
   |
16 |     let lines = BufReader::new(files.input_file).lines();
   |                                ^^^^^^^^^^^^^^^^ move occurs because `files.input_file` has type `File`, which does not implement the `Copy` trait

但准确地说,我不想复制。 我只想使用我已经检查过的文件。 我尝试使用可变引用和字段。 同样的错误。

正如错误所暗示的那样, BufReader::new正在尝试移动files.input_files ,它位于共享引用 ( &FileHandler ) 之后。 为了让它不移动files.input_file ,请改用对它的引用:

use std::fs::File;
use std::io::{BufRead, BufReader};

struct FileHandler {
    input_file: File,
}

impl FileHandler {
    fn setup(in_file_name: &str) -> Self {
        let i_file = File::open(in_file_name).unwrap();
        Self { input_file: i_file }
    }
}

fn process_file(files: &FileHandler) {
    // --- CHANGED ---
    let lines = BufReader::new(&files.input_file).lines();

    for _ln in lines {
        println!("one more line");
    }
}

fn main() {
    let files = FileHandler::setup("foo.txt");
    process_file(&files);
}

发生这种情况是因为BufReader是通用的。 如果你给它一个值,它会移动它,如果你给它一个引用,它只会使用引用。 查看 The Book 中的“ Understanding Ownership ”,了解有关所有权如何运作的更多信息。

let files = FileHandler::setup("foo.txt");

这将创建一个FileHandler结构,它在input_file属性中存储另一个名为File的结构。

files结构拥有其属性的所有权。 所以files拥有input_file

如果您像这样直接使用该input_file属性:

some_function(files.input_file);

这意味着input_file的所有权将移至该 function。

但是如果你这样做那么如果我再次尝试访问files.input_file会发生什么? 也许在some_function内部,存储在input_file属性中的结构被破坏了?

所以我不能再像files.input_file那样使用它了。


解决方案:

使用input_file的引用,所以它是借用的,而不是移动的:

some_function(&files.input_file);

或者在你的这种情况下:

BufReader::new(&files.input_file);

(顺便说一句,恕我直言,我建议您可以使用new而不是setup 。使用通常由new的 function 管理的一些设置创建结构。FileHandler FileHandler::new()对 Rust 开发人员来说更为熟悉。比如BufReader::new()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM