In JavaScript, I can destructure an array in the following way:
const [first, second, ...rest] = myArray
Is there a similar way to achieve this in rust?
If I only want one element, it's easy. I can do:
let first = my_vec[0];
or if I make an array from a string and only want to split i once, in to two parts I can do that and get a tuple with this (if I only need to split the array in to two parts):
let (first, second) = my_string.split_once("\n").unwrap();
But what about the more general destructuring pattern where I can ignore parts of the array and have a few variables defined and ready to go?
I'm expecting it to look something like this:
let [first, second, ...] = my_vec;
or
let [first, ..middle, second_last, last] = my_vec;
P.S.: forget about the unwrap
-part. I know I should handle the error, but that's not the point here.
I tried using a match expression, which didn't work. It expects the array to be of length 2.
let [first, second] = match my_vec[..] {
[first, second] => [first, second],
v => v,
};
I complains about v
and says: `match` arms have incompatible types expected array `[&str; 2]`, found slice `[&str]
.
That makes sense, so is there a way to achieve this?
You can use match
statement with [first, middle @ .., last]
as pattern. This will bind the first
and last
values, and store the rest of them in a single array(middle
).
fn main() {
let my_vec = vec![1, 2, 3, 4, 5];
match my_vec.as_slice() {
[first, middle @ .., last] => {
println!("{:?}, {:?}, {:?}", first, middle, last)
},
_ => {
}
}
}
This will result in following output.
1, [2, 3, 4], 5
You can also use if let
syntax:
fn main() {
let my_vec = vec!["first", "second"];
if let [first, middle @ .., last] = my_vec.as_slice() {
println!("{:?} {:?} {:?}", first, middle, last);
} else {
panic!("The slice is either empty or contains only single element")
};
}