Search code examples
vectorrustdestructuring

Is is possible to deconstruct a vector?


I am toying around with Rust, and am trying to take in some input, and then splitting it by white space in to a vector of strings.

I then want to destructure these inputs again in to separate values. What I have so far is this:

use std::io;

fn main() {
    println!("___Calculator___");

    let mut buffer = String::new();
    
    println!("What would you like to calculate?");

    io::stdin()
        .read_line(&mut buffer)
        .unwrap();
    
    let elements = buffer
        .split_whitespace()
        .collect::<Vec<&str>>();

    let [first, second, third] = elements[0..2];
}

Again, I know I could just read input 3 times, but I want to see how I can do different things with the language.

Edit

Here's the error from cargo run:

   Compiling calculator v0.1.0 (E:\code\rust\calculator)
error[E0005]: refutable pattern in local binding: `[]`, `[_]`, `[_, _]` and 1 more not covered
  --> src\main.rs:18:9
   |
18 |     let [first, second, third] = elements[0..2];
   |         ^^^^^^^^^^^^^^^^^^^^^^ patterns `[]`, `[_]`, `[_, _]` and 1 more not covered
   |
   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
   = note: the matched value is of type `[&str]`
help: you might want to use `if let` to ignore the variants that aren't matched
   |
18 |     let (first, second, third) = if let [first, second, third] = elements[0..2] { (first, second, third) } else { todo!() };
   |     +++++++++++++++++++++++++++++++                                             +++++++++++++++++++++++++++++++++++++++++++

For more information about this error, try `rustc --explain E0005`.
error: could not compile `calculator` due to previous error

Thanks


Solution

  • Rust doesn't understand that elements[0..2] is always going to be three elements. In fact, it potentially won't be, if the user enters fewer than three words. So you need to handle that case.

    if let [first, second, third] = &elements[0..2] {
      ...
    } else {
      println!("Enter three words plz :(");
    }
    

    EDIT: From a comment on the question, you also want elements[0..3]. Ranges are half-open in Rust.