The Option::and_then function simplifies this code:
let foo = Some (1); let bar = match foo { Some (i) => Some (i+1), None => None }; println! ("Foo: {:?}", foo);
in it:
let foo = Some (1); let bar = foo.and_then (|i| Some(i+1)); println! ("Foo: {:?}", foo);
However, if I try to do the same with strings, it does not compile:
let foo = Some ("bla".to_string()); let bar = foo.and_then (|ref f| Some (f.clone())); println! ("Foo: {:?}", foo);
Gives error: use of moved value: 'foo' , because String not copied, which causes foo to move when and_then . However, the corresponding match expression works:
let foo = Some ("bla".to_string()); let bar = match foo { Some (ref f) => Some (f.clone()), None => None }; println! ("Foo: {:?}", foo);
Is there a way to shorten this expression of correspondence, for example, my first example with integers?
Thanks.
Playground Code
Edit
In response to some of the comments:
In this minimal example, I could use map , but in my real code, I call another function that returns Option , so I really need and_then . I just did not want to unnecessarily complicate the example with an additional function that did not affect the problem.
I really need to use foo after this, otherwise there would be no problem (in fact, foo captured by the closure, which I need to use more than once, and Man! It's hard to keep track of why the compiler kept giving up my code! Error the trait FnMut... is not implemented for the type [ closure@... ] does not give much indication of why this is not so).
I used clone in this example because I need a simple operation using a string. In real code, foo not a string (this is a Regex ), and I do not clone it in a close (I apply it to the string and process the results). Moreover, this code will be called many times, so it is important to avoid unnecessary distributions and copies.
as_ref is what I wanted. I was looking for something similar in the docs, and I don't understand how I could have missed it. Thanks for the help!
source share