I have a struct like that
#[derive(Copy, Clone)] enum Command { Quit, Error { msg: String }, }
The compiler complains that it cannot generate a copy constructor for Error
.
I need to make the struct copyable to pass over a channel to another thread.
error: the trait `Copy` may not be implemented for this type; variant `Error` does not implement `Copy` [E0205] #[derive(Copy, Clone)] ^~~~~~~~~~~~~~~~~~~~~~ note: in this expansion of #[derive_Copy] (defined in src/main.rs)
It compiles if msg
is an i32
. It looks strange that such basic type as String
is not copyable.
String can't implement Copy because (like Vec and any other variable-sized container), it contains a pointer to some variable amount of heap memory. The only correct way to copy a String is to allocate a new block of heap memory to copy all the characters into, which is what String 's Clone implementation does.
If you want to copy only pointer to the string, you can change the struct declaration as below and manually manage the memory for the string via functions Test_init and Test_delete . Show activity on this post.
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).
You can simply copy string objects in C++ using = assignment operator.
For me looks strange that such basic type as string is not copyable.
Rust is explicit first.
One of the oft heard complains from C programmers (and most notably Linus Torvald) with regard to C++ is that there is too much implicit copying in C++, which hides memory allocation. Coupled with implicit conversions, they can really creep in the most unexpected places.
Rust instead is designed with an intent to expose the complexity of the underlying operations. It does implicitly perform some conversions (borrowing, from &T
to &Trait
), but those are cheap (and generally constant time).
This explicitness shows in the two traits you have here:
Clone
is about indicating how to create a new instance, and must be called explicitly. Most types (but not all) can be copied using it.
Copy
is a specific compiler trait which indicates that the developer wishes to activate implicit copying for the type; it is only available if a shallow copy is equivalent to a deep copy, which ensures that no memory allocation will occur as part of those implicit copies
So, to ensure your remark:
String
is copyable, use .clone()
String
is not implicitly copyable, because that would cause non-obvious memory allocations to occurIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With