I'd like to bind a variable to a vector (collected from an iterator: lines.take(5).collect::<Vec<_>>()) based on the length of said vector; (i.e. v.len() == 5). Thus I'd like to bind it as something like this:
match lines.take(5).collect::<Vec<_>>() {
e @ e.len() == 5 => todo!(),
_ => panic!(),
}
I've consulted the Patterns documentation (in the Rust Reference), and so far it seems that this is only implemented for constant values. However, I wanted to confirm if that indeed is the case.
(What I actually want to do is continue looping until the length of the collected vector is not 5; I would also like to use the variable inside the loop. The vector is generated again every time, so what looked best was to assign the value and test it within the loop conditional itself with a while let)
I'm not entirely sure what you want, but from the sample code it sounds like you want a match guard. Guards are not part of patterns (which can indeed only compare against constants), but part of match's syntax, and they are written with if instead of @:
match lines.take(5).collect::<Vec<_>>() {
e if e.len() == 5 => todo!(),
_ => panic!(),
}
Another possibility that might be of interest for matching an exact length is to use a slice pattern:
let mut v: Vec<_> = lines.take(5).collect();
while v.len() == 5 {
/* ...use `v` with 5 elements... */
// Reuse `v` for the next iteration
v.clear();
v.extend(lines.take(5));
}
/* ...optionally use `v` with less than 5 elements... */
Thank you! Match guards were exactly what I was looking for. It seems I missed them because I was searching through if let's documentation, which only allows patterns, and I thought that match arms also exclusively took patterns.