I'm wondering if there are some general guidelines about when the Copy
trait should be used.
I think I generally understand that it should be used on "plain-old data" that resides only on the stack.
I was working with some code that generally looked like:
enum Color {
Red,
Blue,
Green,
}
fn print_color_borrow(color: Color) {
match color {
_ => {}
}
}
Before realizing that I didn't want to move the enum instance, so I figured passing a reference in would solve the problem:
enum Color {
Red,
Blue,
Green,
}
fn print_color_borrow(color: &Color) {
match *color {
_ => {}
}
}
But I was dissatisfied with the additional *
making this code feel slightly more complex to read (I probably need to stop thinking in terms of C++). Then I realized that in C/C++ this trival enum would just be implemented as an i32
, so why not just copy it?
#[derive(Copy, Clone)]
enum Color {
Red,
Blue,
Green,
}
fn print_color_borrow(color: Color) {
match color {
_ => {}
}
}
I think this is the correct solution, but it made me start thinking about if large enum
s or structs
would incur a performance penalty if copied.
#[derive(Copy, Clone)]
struct BigStruct {
a: i64,
b: i64,
c: i64,
d: i64,
e: i64,
...
}
Would it be more efficient to pass a reference to BigStruct
rather than copy it, even though it is plain-old-data? On say, a modern x86_64 machine is there a cutoff (pointer size?) that a programmer should be thinking about when making these kinds of decisions? Would that change if you were considering other platforms (e.g. 32-bit ARM)?