【问题标题】:How do you copy between arrays of different sizes in Rust?如何在 Rust 中不同大小的数组之间进行复制?
【发布时间】:2014-08-10 03:45:54
【问题描述】:

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

let mut array1 = [0; 8];
let array2 = [1, 2, 3, 4];

如何将array2 复制到array1 的前4 个字节中?我可以获取 array1 的可变 4 字节切片,但我不确定如何或是否可以分配给它。

【问题讨论】:

    标签: arrays rust


    【解决方案1】:

    手动即可

    for (dst, src) in array1.iter_mut().zip(&array2) {
        *dst = *src
    }
    

    对于一个典型的切片。但是,clone_from_slice 的专业化可能更快:

    dst[..4].clone_from_slice(&src)
    

    一种稍旧的方法是使用std::io::Write,它是为&mut [u8] 实现的。

    use std::io::Write;
    let _ = dst.write(&src)
    

    这将写入直到dst 的末尾,并返回在Result 中写入了多少值。如果您使用write_all,如果不是所有字节都可以写入,这将返回Err

    【讨论】:

      【解决方案2】:

      最灵活的方式是使用迭代器依次处理每个元素:

      for (place, data) in array1.iter_mut().zip(array2.iter()) {
          *place = *data
      }
      

      .mut_iter 创建an Iterator that yields &mut u8,即指向切片/数组的可变引用。 iter 做同样的事情,但使用 shared references.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));
        

        (如果您知道array1 总是比array2 长,那么bytes::copy_memory(array1.mut_slice_to(array2.len()), array2) 也应该可以工作。)

      目前,bytes 版本的优化效果最好,最低为 memcpy 调用,但希望 rustc/LLVM 的改进最终能实现这一目标。

      【讨论】:

      • 请注意,mut_iter 至少从 1.0.0 (可能更早?)起已重命名为 iter_mut
      • 可以确认,WiSaGaN。编辑答案以添加您的更正。
      【解决方案3】:

      您可以简单地使用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]);
      }
      

      反例:

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

      组合案例:

      fn main() {
          let src = [1, 2, 3, 4, 5, 6, 7, 8];
          let mut dest = [0; 4];
      
          dest[1..3].copy_from_slice(&src[3..5]);
      
          assert_eq!(dest, [0, 4, 5, 0]);
      }
      

      【讨论】:

        猜你喜欢
        • 2011-07-30
        • 1970-01-01
        • 2020-12-02
        • 2015-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-15
        相关资源
        最近更新 更多