.and_then() on Result with function that's borrowing


#1

The .and_then() method is pretty useful, but how do I use it with a function that expects a reference? Using a closure works, but I wondered if there is a more elegant alternative.

fn add(x: &u32) -> Result<u32, u32> { Ok(*x + *x) } //stupid example

fn main() {
    assert_eq!(Ok(2).and_then(|x| add(&x)), Ok(4)); // works, but closure
    assert_eq!(Ok(2).as_ref().and_then(add), Ok(4)); // type error
}

http://is.gd/26gps3

.as_ref() also turns the Err variant of the result into a reference, which collides with the result type of add in the example.


#2

I don’t think there is a better way than using a closure, which is still quite nice and readable.

Sometimes you may even need to write a closure like |x| add(x) because of auto-(de)ref magic applied by Rust for function arguments :smile:


#3

I’d just write the closure, personally. But you could also do .as_ref().map_err(Clone::clone), as long as your error type implements Clone.

If that’s too verbose, you could write an ok_ref method that’s equivalent: http://is.gd/SgLT0Q


#4

The solution using the ok_ref method is nice. I did not know it’s possible to implement traits on module foreign types. On a second read of the rust book, it’s quiet obvious it is allowed :).

Does rustc actually optimise this kind of redirection (using closures) away?

.and_then(|x| add(&x))

Thank you!


#5

It does.