Reputation: 2545
I am currently doing the following:
let line_parts = line.split_whitespace().take(3).collect::<Vec<&str>>();
let ip = line_parts[0];
let bytes = line_parts[1];
let int_number = line_parts[2];
Is it possible to do something like this?
let [ip, bytes, int_number] = line.split_whitespace().take(3).collect();
I'm noticed various references to vector destructuring on some sites but the official docs don't seem to mention it.
Upvotes: 33
Views: 17639
Reputation: 56
You can do this:
let line = "127.0.0.1 1000 3";
let [ip, bytes, int_number]: [&str; 3] = line
.split_whitespace()
.take(3)
.collect::<Vec<_>>()
.try_into()
.unwrap();
Upvotes: 0
Reputation: 211
You can also use this:
use std::convert::TryFrom;
let v = line.split_whitespace().take(3).collect::<Vec<&str>>();
let [ip, bytes, int_number] = <[&str; 3]>::try_from(v).ok().unwrap();
The return type of <[&str; 3]>::try_from(v)
will be the Result
type which you can use for error handling or allow it to panic as I did, since we already know that the size is 3.
Upvotes: 11
Reputation: 14511
It seems what you need is "slice patterns":
fn main() {
let line = "127.0.0.1 1000 what!?";
let v = line.split_whitespace().take(3).collect::<Vec<&str>>();
if let [ip, port, msg] = &v[..] {
println!("{}:{} says '{}'", ip, port, msg);
}
}
Note the if let
instead of plain let
. Slice patterns are refutable, so we need to take this into account (you may want to have an else
branch, too).
Upvotes: 48