【问题标题】:Reading a file with Rust - borrowed value only lives until here用 Rust 读取文件 - 借来的值只存在到这里
【发布时间】:2018-12-13 05:31:48
【问题描述】:

我有一个函数应该读取一个文件并返回它的内容。

fn read (file_name: &str) -> &str {

    let mut f = File::open(file_name)
        .expect(&format!("file not found: {}", file_name));

    let mut contents = String::new();

    f.read_to_string(&mut contents)
        .expect(&format!("cannot read file {}", file_name));

    return &contents;
}

但我得到这个错误:

  --> src\main.rs:20:13
   |
20 |     return &contents;
   |             ^^^^^^^^ borrowed value does not live long enough
21 | }
   | - borrowed value only lives until here
   |

我做错了什么?

我对这里发生的事情的想法是这样的:

  1. let mut f = File::open(file_name).expect(....); - 它获取一个文件句柄并告诉操作系统我们想要对它做些什么。

  2. let mut contents = String::new(); - 这会在堆上创建一个类似向量的数据结构,以便存储我们即将从文件中读取的数据。

  3. f.read_to_string(&mut contents).expect(...); - 这会将文件读入contents 空间。

  4. return &contents; - 返回指向存储文件数据的向量的指针。

为什么我不能返回我想要的指针?

如何关闭我的文件(f 变量)?我认为 rust 会在变量超出范围后为我关闭它,但如果我需要在此之前关闭它怎么办?

【问题讨论】:

    标签: rust


    【解决方案1】:

    当变量超出范围时,文件句柄自动关闭是正确的;不过,contents 也会发生同样的情况 - 它将在函数结束时被销毁,除非您决定将其作为拥有的String 返回。在 Rust 中,函数不能返回对其内部创建的对象的引用,只能返回作为参数传递给它们的对象。

    您可以按如下方式修复您的功能:

    fn read(file_name: &str) -> String {
        let mut f = File::open(file_name)
            .expect(&format!("file not found: {}", file_name));
    
        let mut contents = String::new();
    
        f.read_to_string(&mut contents)
            .expect(&format!("cannot read file {}", file_name));
    
        contents
    }
    

    或者,您可以将contents 作为对read 函数的可变引用传递:

    fn read(file_name: &str, contents: &mut String) { ... }
    

    【讨论】:

    • 如果你从函数返回String而不是指针,这是否意味着你正在将它复制到内存中?
    • @HristoKolev:移动语义背后的细节是 a separate topic 和潜在的 LLVM 优化是 a whole different story 但是,总的来说(除了一些 unsafe 魔术之外),这是它的完成方式在 Rust 中。
    • 但是如果我将它作为mut 参数传递它不会进行任何复制?
    • @HristoKolev:一般来说不应该 - 在大多数情况下,这应该被优化掉。如果您愿意,您可以随时使用this question 中的地址进行验证。
    • 请注意,如果您从函数返回String,它可能会复制String struct(即一个指针和一个int),但它不会'不复制在堆上分配并由指针引用的字符串data
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多