If I have two arrays of different sizes:
let mut array1 = [0; 8];
let array2 = [1, 2, 3, 4];
How would I copy array2
into the first 4 bytes of array1
? I can take a mutable 4 byte slice of array1, but I'm not sure how or if I can assign into it.
In this article, we will see how to solve Copy An Array in rust code with examples. let arr =["a","b","c"]; // ES6 way const copy = [... arr]; // older method const copy = Array. from(arr);
Arrays of any size implement the following traits if the element type allows it: Copy. Clone. Debug.
The length of an array is the number of elements present in the array. We use the len() function to obtain this value.
There is no way to do this in stable Rust; arrays cannot have values added or removed at runtime; their lengths are fixed at compile time.
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 like array1.copy_from(array2)
.
std::slice::bytes::copy_memory
, although you will need to trim the two arrays because copy_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 than array2
then bytes::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]);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With