How to I make `unwrap_or` to return a vector of zeroes?

Viewed 45

I have a struct with an Option<Vec<...>>, and at some point need to produce either data contained in it, or an array of zeroes in the case of None. I've tried multiple approaches but I always get stuck with a compile error. How should I code the bar function?

pub struct Foo {
  pub data: Option<Vec<u32>>
}

impl Foo {
  fn bar(&self) -> &Vec<u32> {
    self.data.as_ref().unwrap_or_else(|| &vec![0, 10])
  }
}

fn main() {
  let foo = Foo { data: None };
  println!("{:?}", foo.bar());
}
> rustc main.rs
error[E0515]: cannot return reference to temporary value
 --> main.rs:7:42
  |
7 |     self.data.as_ref().unwrap_or_else(|| &vec![0, 10])
  |                                          ^-----------
  |                                          ||
  |                                          |temporary value created here
  |                                          returns a reference to data owned by the current function

error: aborting due to previous error

For more information about this error, try `rustc --explain E0515`.
1 Answers

As others have indicated, returning a slice is preferable for other reasons, but it also makes the implementation of this method easier -- you can just take a slice of a static array:

pub struct Foo {
  pub data: Option<Vec<u32>>
}

impl Foo {
  fn bar(&self) -> &[u32] {
    self.data.as_deref().unwrap_or(&[0; 10])
  }
}

fn main() {
  let foo = Foo { data: None };
  println!("{:?}", foo.bar());
}

(Playground)

Related