How do you copy between arrays of different sizes in Rust?
Manually one can do
for (dst, src) in array1.iter_mut().zip(&array2) {
*dst = *src
}
for a typical slice. However, there is a likely faster specialization in clone_from_slice
:
dst[..4].clone_from_slice(&src)
A slightly older method is to use std::io::Write
, which was implemented for &mut [u8]
.
use std::io::Write;
let _ = dst.write(&src)
This will write up to the end of dst
and return how many values were written in a Result
. If you use write_all
, this will return an Err
if not all bytes could be written.
The most flexible way is to use iterators to handle each element successively:
for (place, data) in array1.iter_mut().zip(array2.iter()) {
*place = *data
}
.mut_iter
creates an Iterator
that yields &mut u8
, that is, mutable references pointing into the slice/array. iter
does the same but with shared references. .zip
takes two iterators and steps over them in lock-step, yielding the elements from both as a tuple (and stops as soon as either one stops).
If you need/want to do anything 'fancy' with the data before writing to place
this is the approach to use.
However, the plain copying functionality is also provided as single methods,
.copy_from
, used likearray1.copy_from(array2)
.std::slice::bytes::copy_memory
, although you will need to trim the two arrays becausecopy_memory
requires they are the same length: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));
(If you know that
array1
is always longer thanarray2
thenbytes::copy_memory(array1.mut_slice_to(array2.len()), array2)
should also work.)
At the moment, the bytes
version optimises the best, down to a memcpy
call, but hopefully rustc
/LLVM improvements will eventually take them all to that.
You could simply use copy_from_slice()
and use 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]);
}
Inverse case:
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]);
}
Combined case:
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]);
}