pub trait Copy: Clone { }
Expand description
Types whose values can be duplicated simply by copying bits.
By default, variable bindings have âmove semantics.â In other words:
#[derive(Debug)]
struct Foo;
let x = Foo;
let y = x;
However, if a type implements Copy
, it instead has âcopy semanticsâ:
#[derive(Debug, Copy, Clone)]
struct Foo;
let x = Foo;
let y = x;
println!("{x:?}");
Itâs important to note that in these two examples, the only difference is whether you are allowed to access x
after the assignment. Under the hood, both a copy and a move can result in bits being copied in memory, although this is sometimes optimized away.
Copy
?
There are two ways to implement Copy
on your type. The simplest is to use derive
:
#[derive(Copy, Clone)]
struct MyStruct;
You can also implement Copy
and Clone
manually:
struct MyStruct;
impl Copy for MyStruct { }
impl Clone for MyStruct {
fn clone(&self) -> MyStruct {
*self
}
}
There is a small difference between the two. The derive
strategy will also place a Copy
bound on type parameters:
#[derive(Clone)]
struct MyStruct<T>(T);
impl<T: Copy> Copy for MyStruct<T> { }
This isnât always desired. For example, shared references (&T
) can be copied regardless of whether T
is Copy
. Likewise, a generic struct containing markers such as PhantomData
could potentially be duplicated with a bit-wise copy.
Copy
and Clone
?
Copies happen implicitly, for example as part of an assignment y = x
. The behavior of Copy
is not overloadable; it is always a simple bit-wise copy.
Cloning is an explicit action, x.clone()
. The implementation of Clone
can provide any type-specific behavior necessary to duplicate values safely. For example, the implementation of Clone
for String
needs to copy the pointed-to string buffer in the heap. A simple bitwise copy of String
values would merely copy the pointer, leading to a double free down the line. 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).
Copy
?
A type can implement Copy
if all of its components implement Copy
. For example, this struct can be Copy
:
#[derive(Copy, Clone)]
struct Point {
x: i32,
y: i32,
}
A struct can be Copy
, and i32
is Copy
, therefore Point
is eligible to be Copy
. By contrast, consider
struct PointList {
points: Vec<Point>,
}
The struct PointList
cannot implement Copy
, because Vec<T>
is not Copy
. If we attempt to derive a Copy
implementation, weâll get an error:
the trait `Copy` cannot be implemented for this type; field `points` does not implement `Copy`
Shared references (&T
) are also Copy
, so a type can be Copy
, even when it holds shared references of types T
that are not Copy
. Consider the following struct, which can implement Copy
, because it only holds a shared reference to our non-Copy
type PointList
from above:
#[derive(Copy, Clone)]
struct PointListWrapper<'a> {
point_list_ref: &'a PointList,
}
§When canât my type be Copy
?
Some types canât be copied safely. For example, copying &mut T
would create an aliased mutable reference. Copying String
would duplicate responsibility for managing the String
âs buffer, leading to a double free.
Generalizing the latter case, any type implementing Drop
canât be Copy
, because itâs managing some resource besides its own size_of::<T>
bytes.
If you try to implement Copy
on a struct or enum containing non-Copy
data, you will get the error E0204.
Copy
?
Generally speaking, if your type can implement Copy
, it should. Keep in mind, though, that implementing Copy
is part of the public API of your type. If the type might become non-Copy
in the future, it could be prudent to omit the Copy
implementation now, to avoid a breaking API change.
In addition to the implementors listed below, the following types also implement Copy
:
fn() -> i32
)Copy
themselves. Note that variables captured by shared reference always implement Copy
(even if the referent doesnât), while variables captured by mutable reference never implement Copy
.This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4