Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should the Copy trait always be implemented if possible?

Tags:

copy

rust

move

You can implement the Copy trait to give the type copy-semantics instead of move-semantics. This can only be done if all its constituent elements (each factor of a product type, or each factor of each variant of a sum-type) are also Copy.

This allows you to also make rather large types Copy. Can implementing Copy be detrimental to performance if the size of the type is "large"?

If Copy should always be implemented, why is it not an auto-trait like Sync and Send for those types which can implement it and have opt-out semantics instead of opt-in?

like image 681
Centril Avatar asked Sep 12 '17 21:09

Centril


People also ask

Does Option implement copy trait?

Option<&mut T> can't implement Clone or Copy because &mut T doesn't, for lifetime reasons. If the compiler supported some special trait, say BorrowCopyOfPointer , then Option<&mut T> could implement that, as could other wrapper types ( &mut T would implicitly implement it).

Does string implement clone rust?

For this reason, String is Clone but not Copy . Clone is a supertrait of Copy , so everything which is Copy must also implement Clone . If a type is Copy then its Clone implementation only needs to return *self (see the example above).

Are references copy rust?

Yes, this is correct. In Rust terms, &T is Copy , which means that it can be copied bitwise without transferring ownership.


1 Answers

why is [Copy] not an auto-trait like Sync and Send for those types which can implement it and have opt-out semantics instead of opt-in?

Copy used to be automatically implemented by types that could implement it. This behavior was changed in December 2014, not too long before Rust 1.0.

Should the Copy trait always be implemented if possible?

Not necessarily. When developing a library, the choice to implement Copy or not on a type has an impact on forward compatibility. Removing a Copy implementation on a type is a breaking change (users of that type may rely on the type being copied instead of moved), and as such would impose a major version bump on the library in order to respect semantic versioning. In particular, if a type is able to implement Copy now but you think it's possible that the type may evolve such that it could no longer implement Copy, you should play it safe and not implement Copy on that type.

Another reason for not implementing Copy is, as you mentioned, large types. It may be useful to implement only Clone for such types, as usually "Clone but not Copy" indicates that cloning the value is not "cheap". However, even if a type is not Copy, one could still cause a large memory copy operation by merely moving the value (though if you're lucky, the compiler might optimize it away).

Can implementing Copy be detrimental to performance if the size of the type is "large"?

Not if you never perform a copy on the type! Keep in mind that the only difference between a move and a copy is that a move makes the source unusable (i.e. the compiler will raise an error if you try to use a value after it was moved), while a copy doesn't; both operations are implemented as a shallow memory copy.

like image 141
Francis Gagné Avatar answered Sep 21 '22 07:09

Francis Gagné