Avoiding while with break


#1

Hi - I’m a Rust-rookie

in C++ I’m used to this type of coding:

AType* ptr = get_some_data_from_somewhere();
while (ptr) {
  process_data(ptr);
  ptr = get_some_data_from_somewhere();
}

where “get_some_data_from_somewhere()” either creates data or returns 0 if no data is available.

Since core::option::Option is the substitute for 0-pointers I wrote some function
fn get_some_data_from_somewhere() -> Option<AType>.

Unfortunately my while-statement became somehow odd;

   while true {
     match get_some_data_from_somewhere() {
        None => break,
        Some(data) => process_data(data)
     }
  }

Is there a way to avoid the while-true-“anti-pattern” ?

Any advice? Thanks
Benedikt


#2

You can combine pattern matching with while:

while let Some(data) = get_some_data_from_somewhere() {
    process_data(data)
}

#3

Uff! Incredible fast and perfect answer.

Awesome :ok_hand:

Benedikt


#4

You can also consider making get_some_data_from_somewhere return an Iterator, and then you get all the iterator goodness (if you need it).

Alternatively, you can use the itertools crate to turn your fn into an iterator:

itertools::repeat_call(get_some_data_from_somewhere)
        .while_some()
        .for_each(process_data);

This is, of course, overkill if you don’t see yourself making use of additional iterator combinators. But just wanted to throw this out there for you.


#5

@jethrogb’s answer is the right one for your use case, but note also that rust has loop { }, so there’s no need for while true { }.


#6

I’d also argue that it’s not really an anti-pattern. There are cases where a loop condition would be more complicated than a relatively simple breaking condition (or two).

(Though I agree in this case, while let is the best way.)