Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a copyable struct containing a String? [duplicate]

Tags:

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.

like image 873
Daniil Iaitskov Avatar asked Jul 11 '16 10:07

Daniil Iaitskov


People also ask

How would you implement a copy trait for string?

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.

How do you copy a struct to a string?

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.

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).

How to Clone a string c++?

You can simply copy string objects in C++ using = assignment operator.


1 Answers

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 occur
like image 139
Matthieu M. Avatar answered Nov 10 '22 04:11

Matthieu M.