Here's a common pattern I find myself running into:
let maybe_vec = Some(vec!["val"]); // I have an option with something in it
maybe_vec.and_then(|vec| vec.get(0)); // then I want to transform the something
This gives me
src/lib.rs:317:34: 317:37 error: `vec` does not live long enough
src/lib.rs:317 maybe_vec.and_then(|vec| vec.get(0));
^~~
src/lib.rs:317:9: 317:45 note: reference must be valid for the method call at 317:8...
src/lib.rs:317 maybe_vec.and_then(|vec| vec.get(0));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/lib.rs:317:34: 317:44 note: ...but borrowed value is only valid for the block at 317:33
src/lib.rs:317 maybe_vec.and_then(|vec| vec.get(0));
^~~~~~~~~~
To me this error seems overly pedantic - vec might not live long enough, but in this particular case vec is the thing inside maybe_vec, which clearly is going to live long enough. Do I need to provide some sort of lifetime annotations here, or am I just going about this wrong?
Unfortunately for you, the compiler is correct here. and_then consumes the Option and the value inside the option along with it. The value is provided to the closure. You can see this by using the trick of assigning a variable to the unit-type (()):
let a = Some(vec![1]);
a.and_then(|z| { let () = z; });
// error: expected `collections::vec::Vec<_>`,
When you call get, it returns a reference to an item in the slice, but the Vec now only lives inside the closure. Once the closure exits, it's gone! Instead, you can change the Option into a reference, then get the value that way. This leaves the original Vec in place:
let a = Some(vec![1]);
a.as_ref().and_then(|z| z.get(0));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With