I am trying to initialise an array of structs in Rust:
enum Direction {
North,
East,
South,
West,
}
struct RoadPoint {
direction: Direction,
index: i32,
}
// Initialise the array, but failed.
let data = [RoadPoint { direction: Direction::East, index: 1 }; 4];
When I try to compile, the compiler complains that the Copy
trait is not implemented:
error[E0277]: the trait bound `main::RoadPoint: std::marker::Copy` is not satisfied
--> src/main.rs:15:16
|
15 | let data = [RoadPoint { direction: Direction::East, index: 1 }; 4];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `main::RoadPoint`
|
= note: the `Copy` trait is required because the repeated element will be copied
How can the Copy
trait be implemented?
#[derive(Clone, Copy)]
is the right way, but for the record, it's not magical: It's easy to implement those traits manually, especially in easy cases such as yours: impl Copy for Direction {} impl Clone for Direction { fn clone(&self) -> Self { *self } }
You don't have to implement Copy
yourself; the compiler can derive it for you:
#[derive(Copy, Clone)]
enum Direction {
North,
East,
South,
West,
}
#[derive(Copy, Clone)]
struct RoadPoint {
direction: Direction,
index: i32,
}
Note that every type that implements Copy
must also implement Clone
. Clone
can also be derived.
Just prepend #[derive(Copy, Clone)]
before your enum.
If you really want, you can also
impl Copy for MyEnum {}
The derive-attribute does the same thing under the hood.
Success story sharing
Clone
is a supertrait ofCopy
so every type implementingCopy
also needs to implementClone
.Clone
without derivingCopy
. It allows developers to do.clone()
on the element explicitly, but it won't do it for you (that'sCopy
's job). So at least there's a reason forClone
to exist separately fromCopy
; I would go further and assumeClone
implements the method, butCopy
makes it automatic, without redundancy between the two.