Beginners query on borrowing and and_then using read_to_string() as an example


#1

so, I wanted to read the contents of a file. i wanted use the result and not just panic if something went wrong, ie not expect. this was my first attempt:

    let r = File::open("a.txt").and_then(|f| {
    let mut s = String::new();
    f.read_to_string(&mut s).and_then(|_| Ok(s))
});

this told me I couldn’t borrow f as mutable. aha! I next tried:
let r = File::open(“a.txt”).as_mut().and_then(|f| {
let mut s = String::new();
f.read_to_string(&mut s).as_mut().and_then(|_| Ok(s))
});

I now get borrowed value does not live long enough. At this point I believe I’m stuck, or is this even possible?

thanks,


#2

|mut f| the error in first code should be containing this.


#3

It wants

let mut /*edit*/f = File...

The .as_mut() isn’t enough, because it’s called on a value that hasn’t been assigned to a variable, so it lives only temporarily for the expression (one line)


#4

I recommend using the ? operator. It’ll save you writing so many and_then().

To avoid panicking, put file reading code in a function, and then match that_function() to handle the error nicely.


#5
    let r = File::open("a.txt").and_then(|mut f| {
    let mut s = String::new();
    f.read_to_string(&mut s).and_then(|_| Ok(s))
});

worked a treat!
I didn’t have so much success with let mut r = File...

Using the ? operator worked nicely, in a do notation style, but the special sauce was it needs to be in a function that returns Result. This gave me:

fn read_text() -> std::io::Result<String> {
let mut f = File::open("a.txt")?;
let mut s = String::new();
f.read_to_string(&mut s)?;
Ok(s)

}

thanks all :slight_smile:


#6

Yup, that’s it!

std::io::Result can be shortened to just Result (the compiler prints the full name, but the Result is available globally).


#7

std::result::Result is, not the io one :slight_smile:


#8

Oh, right. I misread.


#9

many thanks. it’s starting to come together now


#10

See also:

https://doc.rust-lang.org/nightly/std/fs/fn.read_to_string.html


#11

thanks. that looks handy