A fixed-length array of a native type (or of a type that implements the Copy
trait) can be cloned in Rust up to the length of 32. That is, this compiles:
fn main() {
let source: [i32; 32] = [0; 32]; // length 32
let _cloned = source.clone();
}
But this doesn't:
fn main() {
let source: [i32; 33] = [0; 33]; // length 33
let _cloned = source.clone(); // <-- compile error
}
In fact, the trait Clone
only declares a method for each generic array length, from 0 to 32.
What is an efficient and idiomatic way to clone a generic array of length, say, 33?
You can't add the impl Clone
in your own code. This problem will be fixed at some point, in the mean time you can mostly work around it with varying amount of effort:
- If you just have a local variable of a concrete type and the type is
Copy
(as in your example), you can simply copy rather than cloning, i.e., let _cloned = source;
.
- If the array is a field of a struct you want to implement
Clone
for (and derive
won't work), you can still manually implement Clone
and using the above trick in the implementation.
- Cloning an array of non-
Copy
types is trickier, because Clone
can fail. You could write out [x[0].clone(), x[1].clone(), ...]
for as many times as you need, it's a lot of work but at least it's certain to be correct.
- If all else fails, you can still create a newtype wrapper. This requires quite a bit of boilerplate to delegate all the other traits you need, but then you can (again, manually) implement
Clone
.
You can clone arbitrary-length arrays since Rust 1.21.0. The "Libraries" section of the CHANGELOG says:
Generate builtin impls for Clone
for all arrays and tuples that are T: Clone