如何在Rust中连接两个切片?

The*_*Cat 11 rust

我想从向量中获取x个第一个和最后一个元素并将它们连接起来.我有以下代码:

fn main() {
    let v = (0u64 .. 10).collect::<Vec<_>>();
    let l = v.len();
    vec![v.iter().take(3), v.iter().skip(l-3)];
}
Run Code Online (Sandbox Code Playgroud)

这给了我错误

error[E0308]: mismatched types
 --> <anon>:4:28
  |
4 |     vec![v.iter().take(3), v.iter().skip(l-3)];
  |                            ^^^^^^^^^^^^^^^^^^ expected struct `std::iter::Take`, found struct `std::iter::Skip`
<anon>:4:5: 4:48 note: in this expansion of vec! (defined in <std macros>)
  |
  = note: expected type `std::iter::Take<std::slice::Iter<'_, u64>>`
  = note:    found type `std::iter::Skip<std::slice::Iter<'_, u64>>`
Run Code Online (Sandbox Code Playgroud)

我怎么得到我vec1, 2, 3, 8, 9, 10?我正在使用Rust 1.12.

blu*_*uss 19

只需.concat()在一片切片上使用:

fn main() {
    let v = (0u64 .. 10).collect::<Vec<_>>();
    let l = v.len();
    let first_and_last = [&v[..3], &v[l - 3..]].concat();
    println!("{:?}", first_and_last);
    // The output is `[0, 1, 2, 7, 8, 9]`
}
Run Code Online (Sandbox Code Playgroud)

这将创建一个新的向量,它可以使用任意数量的切片.

(游乐场链接)

  • @Rawler 现在在 Rust 1.62.1 上工作得很好。 (6认同)

DK.*_*DK. 15

好的,首先,您的初始序列定义是错误的.你说你想要1, 2, 3, 8, 9, 10输出,所以它看起来像:

    let v = (1u64 .. 11).collect::<Vec<_>>();
Run Code Online (Sandbox Code Playgroud)

接下来,你说你想连接切片,所以让我们实际使用切片:

    let head = &v[..3];
    let tail = &v[l-3..];
Run Code Online (Sandbox Code Playgroud)

一点上,它真的取决于你最喜欢哪种方法.你可以把这些切片变成迭代器,链,然后收集......

    let v2: Vec<_> = head.iter().chain(tail.iter()).collect();
Run Code Online (Sandbox Code Playgroud)

...或制作一个vec并直接用切片延伸...

    let mut v3 = vec![];
    v3.extend_from_slice(head);
    v3.extend_from_slice(tail);
Run Code Online (Sandbox Code Playgroud)

...或者使用更一般的迭代器扩展(这将在未来成为专业化等价的,但我不相信这是高效,只是还没有)...

    let mut v4: Vec<u64> = vec![];
    v4.extend(head);
    v4.extend(tail);
Run Code Online (Sandbox Code Playgroud)

...或者你可以使用Vec::with_capacitypush循环,或做链式迭代器的事情,但使用extend...但我必须在某个时候停止.

完整示例代码:

fn main() {
    let v = (1u64 .. 11).collect::<Vec<_>>();
    let l = v.len();

    let head = &v[..3];
    let tail = &v[l-3..];

    println!("head: {:?}", head);
    println!("tail: {:?}", tail);

    let v2: Vec<_> = head.iter().chain(tail.iter()).collect();
    println!("v2: {:?}", v2);

    let mut v3 = vec![];
    v3.extend_from_slice(head);
    v3.extend_from_slice(tail);
    println!("v3: {:?}", v3);

    // Explicit type to help inference.
    let mut v4: Vec<u64> = vec![];
    v4.extend(head);
    v4.extend(tail);
    println!("v4: {:?}", v4);
}
Run Code Online (Sandbox Code Playgroud)

  • `extend()` 很快就会专门化为 `extend_from_slice()`;它在几天前被合并:[Specialize Vec::extend to Vec::extend_from_slice](https://github.com/rust-lang/rust/pull/37094)。 (2认同)
  • 让v =(1u64 .. 11).collect :: &lt;Vec &lt;_ &gt;&gt;();` ``让v:Vec &lt;u64&gt; =(1..11).collect();` (2认同)

lje*_*drz 6

你应该collect()的结果take()extend()它们与collect()的ED结果skip()

let mut p1 = v.iter().take(3).collect::<Vec<_>>();
let p2 = v.iter().skip(l-3);

p1.extend(p2);

println!("{:?}", p1);
Run Code Online (Sandbox Code Playgroud)

编辑:正如Neikos所说,您甚至不需要收集的结果skip(),因为它extend()接受实现的参数IntoIteratorSkip实际上是Iterator)。

编辑2:不过,您的电话号码有些不对劲;为了得到1, 2, 3, 8, 9, 10你应该声明v如下:

let v = (1u64 .. 11).collect::<Vec<_>>();
Run Code Online (Sandbox Code Playgroud)

由于Range左关闭,右打开。

  • 您无需收集`Skip`,因为`extend`可以采用迭代器 (2认同)