如何从向量中解构元素(unpack/destructure)?

27
我目前正在做以下事情:
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];

可以做这样的事情吗?
let [ip, bytes, int_number] = line.split_whitespace().take(3).collect();

我在一些网站上注意到了关于向量解构的各种引用,但官方文档似乎没有提到它。

个人而言,我会使用 let mut parts = line.split_whitespace(); 然后是 let (ip, bytes, int_number) = (parts.next().unwrap(), parts.next().unwrap(), parts.next().unwrap()); 或者更可能的是 if let (Some(ip), Some(bytes), Some(int_number)) = (parts.next(), parts.next(), parts.next()) - Chris Morgan
2个回答

41

看起来你需要的是“切片模式”:

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);
    }
}

Playground链接

请注意使用if let而不是普通的let。切片模式是可反驳的,因此我们需要考虑这一点(您可能也需要一个else分支)。


2
2015年的回答,似乎在Rust 1.26中稳定了切片模式(链接)。非常好,但是对于具有多个绑定的不可反驳模式的else情况会有些麻烦... - jv-dev

8
你也可以使用这个:
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();
<[&str; 3]>::try_from(v)的返回类型将是Result类型,您可以将其用于错误处理,或者像我一样允许它出现恐慌,因为我们已经知道大小是3。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接