...
// `next_if` saves the value of the next item if it was not equal to `expected`.
assert_eq!(iter.next(), Some(1));
I don't see how this is related. The next item is saved in Peekable's peeked field, but the iterator itself does not (should not?) advance when peeking. The next line with assert_eq(...) shows exactly that.
Is it just badly worded or am I missing something about next_if's actual behavior?
Another question I have is also about Peekable::next_if. It's match statement looks like this:
match self.next() {
Some(matched) if func(&matched) => Some(matched),
other => {
// Since we called `self.next()`, we consumed `self.peeked`.
assert!(self.peeked.is_none());
self.peeked = Some(other);
None
}
}
What is the other match arm? What matches against other and what even is other? My google-fu didn't help, so I'm a little bit lost.
The pattern in the second arm is just a variable name, so it will match anything. It's analogous to let other = [some value]. So in this case, other is either None or Some(did_not_match). And so self.peeked is set to Some(Some(did_not_match)) or Some(None). Then None is returned.
I just don't see how this is related to the following assert_eq(..) that demonstrates that the iterator was not advanced.
It's the first time I see this pattern. I haven't seen it in the rust book or in rust-by-example or in the reference. Do you happen to have a link to some more documentation about this?
You know, that's a really good point. I skimmed all the usual references on match and the examples with a catch-all always use the non-binding _. So I don't have a reference for that in particular, but for a real short version, you can think of it as "a catch-all like _ but it assigns the value to the variable name".
However, it's useful to realize that the patterns in a match can also be used in a lot of other places. In particular for this discussion, let is based around patterns too:
let x = Some(1);
let Some(y) = x; // Like in a match, this works
assert_eq!(y, 1);
let _ = y; // you can do this too
This won't work because let requires an irrefutable pattern, e.g. a pattern that always matches. Here the None pattern is not covered, so the match could fail.
One way to ensure you’ve covered every possibility is to have a catchall pattern for the last arm: for example, a variable name matching any value can never fail and thus covers every remaining case.
Thanks. I see it now. Looks like I was too negligent while reading the book, i.e. to dumb to read properly.