Q:

Reading a file with Rust - borrowed value only lives until here

I have a function that should read a file and returns it's contents.
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;
}

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

What am I doing wrong?
My Idea of what is happening here is this:

let mut f = File::open(file_name).expect(....); - this takes a handle of a file and tells the OS that we want to do things with it.
let mut contents = String::new(); - this creates a vector-like data structure on the heap in order to store the data that we are about to read from the file.
f.read_to_string(&mut contents).expect(...); - this reads the file into the contents space.
return &contents; - this returns a pointer to the vector where the file data is stored.

Why am I not able to return the pointer that I want?
How do I close my file (the f variable)? I think that rust will close it for me after the variable goes out of scope, but what If I need to close it before that?

A:

You are correct about the file handle being closed automatically when its variable goes out of scope; the same will happen to contents, though - it will be destroyed at the end of the function, unless you decide to return it as an owned String. In Rust functions can't return references to objects created inside them, only to those passed to them as arguments.
You can fix your function as follows:
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
}

Alternatively, you can pass contents as a mutable reference to the read function:
fn read(file_name: &str, contents: &mut String) { ... }

