有没有办法将迭代器解压缩成元组?

and*_*man 13 rust

有没有办法完成以下内容:

let v = vec![1, 2, 3];
let (a, b) = v.iter().take(2);
Run Code Online (Sandbox Code Playgroud)

这样a = 1b = 2在结束了吗?

我知道我可以使用矢量但我想要命名变量.

hel*_*s35 11

这可能不是你要求的,但我想你很少想要将任意大的矢量转换为元组.如果您只想将矢量的前几个元素提取到元组中,则可以使用夜间实验特征切片模式匹配来实现:

#![feature(slice_patterns)]

fn main() {
    let v = vec![1, 2, 3];
    let (a, b) = match &v[..] {
        &[first, second, ref _tail..] => (first, second),
        _ => unreachable!(),
    };
    assert_eq!((a, b), (1, 2));
}
Run Code Online (Sandbox Code Playgroud)

  • 从`rustc 1.12.0`开始,切片模式语法仍然是实验性的.见[问题#23121](https://github.com/rust-lang/rust/issues/23121) (2认同)

小智 10

迭代工具箱有方法,如tuplesnext_tuple,可以帮助这一点.

extern crate itertools;

use itertools::Itertools;

fn main() {
    let v = vec![1, 2, 3];
    let (a, b) = v.iter().next_tuple().unwrap();

    assert_eq!(a, &1);
    assert_eq!(b, &2);
}
Run Code Online (Sandbox Code Playgroud)

  • [collect_tuple](https://docs.rs/itertools/0.10.0/itertools/trait.Itertools.html#method.collect_tuple) 也相关 (3认同)

Jes*_*ain 5

我写了这个丑陋的递归宏,将 a 转换Vec为元组,因为我想了解一些有关宏的知识。

macro_rules! tuplet {
    { ($y:ident $(, $x:ident)*) = $v:expr } => {
        let ($y, $($x),*) = tuplet!($v ; 1 ; ($($x),*) ; ($v[0]) );
    };
    { $v:expr ; $j:expr ; ($y:ident $(, $x:ident)*) ; ($($a:expr),*) } => {
        tuplet!( $v ; $j+1 ; ($($x),*) ; ($($a),*,$v[$j]) )
    };
    { $v:expr ; $j:expr ; () ; $accu:expr } => {
        $accu
    }
}
Run Code Online (Sandbox Code Playgroud)

我对此很陌生,可能很不擅长,所以很可能有更好的方法来做到这一点。这只是一个概念证明。它允许你写:

fn main() {
    let v = vec![1, 2, 3];
    tuplet!((a, b, c) = v);

    assert_eq!(a, 1);
    assert_eq!(b, 2);
    assert_eq!(c, 3);
}
Run Code Online (Sandbox Code Playgroud)

在该宏定义的某个地方,您可以找到 part $v[$j]$v.nth($j)如果您想将其用于迭代器,您可以将其替换为。