如何在Rust中不同大小的数组之间进行复制?

Pau*_*l D 4 arrays rust

如果我有两个不同大小的数组:

let mut array1 = [0; 8];
let array2 = [1, 2, 3, 4];
Run Code Online (Sandbox Code Playgroud)

我将如何复制array2到前4个字节array1?我可以采用一个可变的4字节slice1,但我不确定如何或如果我可以分配它.

Vee*_*rac 7

手动一个可以做

for (dst, src) in array1.iter_mut().zip(&array2) {
    *dst = *src
}
Run Code Online (Sandbox Code Playgroud)

对于典型的切片。但是,在以下方面可能有更快的专业化clone_from_slice

dst[..4].clone_from_slice(&src)
Run Code Online (Sandbox Code Playgroud)

一个稍微旧的方法是使用std::io::Write,它是为&mut [u8].

use std::io::Write;
let _ = dst.write(&src)
Run Code Online (Sandbox Code Playgroud)

这将写入末尾dst并返回在Result. 如果您使用write_all,这将返回Err如果不是所有字节都可以写入。


huo*_*uon 6

最灵活的方法是使用迭代器连续处理每个元素:

for (place, data) in array1.mut_iter().zip(array2.iter()) {
    *place = *data
}
Run Code Online (Sandbox Code Playgroud)

.mut_iter产生一个Iterator产生&mut u8,即指向切片/数组的可变引用.iter做同样但有共享参考..zip在锁定步骤中获取两个迭代器并跨过它们,从而将元素作为元组产生(并且一旦停止,就停止).

如果你需要/想要在写入之前对数据做任何"花哨"的事情place就是使用方法.

但是,普通复制功能也作为单个方法提供,

  • .copy_from,用过像array1.copy_from(array2).

  • std::slice::bytes::copy_memory,虽然您需要修剪两个数组,因为copy_memory它们需要相同的长度:

    use std::cmp;
    use std::slice::bytes;
    
    let len = cmp::min(array1.len(), array2.len());
    bytes::copy_memory(array1.mut_slice_to(len), array2.slice_to(len));
    
    Run Code Online (Sandbox Code Playgroud)

    (如果你知道array1总是比array2那时长bytes::copy_memory(array1.mut_slice_to(array2.len()), array2)也应该工作.)

目前,该bytes版本优化了最佳,直至memcpy调用,但希望rustc/ LLVM的改进最终会将它们全部用于此.

  • 请注意,至少从 1.0.0(可能更早?) (3认同)

Sta*_*eur 6

您可以简单地使用copy_from_slice()和使用Range & Co

fn main() {
    let mut dest = [0; 8];
    let src = [1, 2, 3, 4];

    dest[..4].copy_from_slice(&src);

    assert_eq!(dest, [1, 2, 3, 4, 0, 0, 0, 0]);
}
Run Code Online (Sandbox Code Playgroud)

逆情况:

fn main() {
    let src = [1, 2, 3, 4, 5, 6, 7, 8];
    let mut dest = [0; 4];

    dest.copy_from_slice(&src[2..6]);

    assert_eq!(dest, [3, 4 ,5, 6]);
}
Run Code Online (Sandbox Code Playgroud)

组合案例:

fn main() {
    let src = [1, 2, 3, 4, 5, 6, 7, 8];
    let mut dest = [0; 4];

    dest.copy_from_slice(&src[2..6]);

    assert_eq!(dest, [3, 4 ,5, 6]);
}
Run Code Online (Sandbox Code Playgroud)