Bind variable based on result of function

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:

    match lines.take(5).collect::<Vec<_>>().as_slice() {
        [a, b, c, d, e] => todo!(),
        _ => panic!(),

Note that to use a slice pattern you need to match a slice (or array), not a Vec, hence the .as_slice().

1 Like

Maybe you want something more like

    let mut v: Vec<_> = lines.take(5).collect();
    while v.len() == 5 {
        /* ...use `v` with 5 elements... */
        // Reuse `v` for the next iteration

    /* ...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.

Thank you once again!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.