87

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?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
tehnyit
  • 1,152
  • 1
  • 9
  • 16
  • 8
    `#[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 } }` –  Feb 17 '16 at 15:02

2 Answers2

115

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.

fjh
  • 12,121
  • 4
  • 46
  • 46
  • 2
    why is the "Clone" needed? Does it always need to be added if one wants to implement Copy? – xetra11 Aug 29 '16 at 04:32
  • 14
    @xetra11Yes, `Clone` is a supertrait of `Copy` so every type implementing `Copy` also needs to implement `Clone`. – fjh Aug 31 '16 at 15:47
  • 5
    It's not exactly an answer, but I rather prefer deriving `Clone` _without_ deriving `Copy`. It allows developers to do `.clone()` on the element explicitly, but it won't do it for you (that's `Copy`'s job). So at least there's a reason for `Clone` to exist separately from `Copy`; I would go further and assume `Clone` implements the method, but `Copy` makes it automatic, without redundancy between the two. – zeh Mar 09 '20 at 13:21
23

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.

llogiq
  • 13,815
  • 8
  • 40
  • 72