1

How should I go about reading the value that's nested within two Options?

I have this code:

struct Person<T> {
    name: &'static str,
    preferences: Vec<&'static str>,
    variant: Option<T>,
}

struct Driver {
    seats: usize,
}

fn main() {
    let list: Vec<Person<Driver>> = todo!();

    let name = "some-name";

    // add a bunch of Person<Driver> drivers to the `list`

    let found = list.iter().find(|candidate| candidate.name == name);

    // other things
}

What's the cleanest or most recommended way to access the field seats from Option<Person<Driver>> in found?

The two ways I've done it is with a nested if let or a nested match. The nested match looks a little ugly, so this is what I'm going with:

if let Some(person) = found {
    if let Some(driver) = &person.variant {
        println!("{:?}", driver.seats);
    }
} 

Is there a better way of going about it?

The reason I have an Option field called variant is since I also have Rider structs and they're literally just a Person. Since both drivers and riders have almost all the same fields, I structured it this way instead of opting to say a person: Person field in each Rider and Driver struct which felt odd.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Aaron
  • 21
  • 7
  • 1
    `if let Some(Some(x)) = ...` or other nested patterns are sometimes useful as well. Applying the duplicate to this case: `if let Some(Person { variant: Some(driver), .. }) = found` – Shepmaster Nov 19 '20 at 19:15
  • 1
    You can also use `if let Some(driver) = found.and_then(|p| p.variant.as_ref())` – Shepmaster Nov 19 '20 at 19:18
  • Ah @Shepmaster, your first comment destructuring the `Person` struct and then destructuring the field `variant` seems to fix it! No compile errors. – Aaron Nov 19 '20 at 19:29
  • 1
    I had tried some variation of that but I don't think I got the right syntax until now! Thanks! – Aaron Nov 19 '20 at 19:29

0 Answers0