Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I tell Rust that my Option's value actually does outlive the closure passed to and_then?

Tags:

rust

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?

like image 694
Caspar Avatar asked Jan 19 '26 05:01

Caspar


1 Answers

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));
like image 164
Shepmaster Avatar answered Jan 21 '26 04:01

Shepmaster