Trait Copy
pub trait Copy: Clone
Types whose values can be duplicated simply by copying bits.
By default, variable bindings have 'move semantics.' In other words:
;
let x = Foo;
let y = x;
// `x` has moved into `y`, and so cannot be used
// println!("{x:?}"); // error: use of moved value
However, if a type implements Copy, it instead has 'copy semantics':
// We can derive a `Copy` implementation. `Clone` is also required, as it's
// a supertrait of `Copy`.
;
let x = Foo;
let y = x;
// `y` is a copy of `x`
println!; // A-OK!
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.
How can I implement Copy?
There are two ways to implement Copy on your type. The simplest is to use derive:
;
You can also implement Copy and Clone manually:
;
There is a small difference between the two. The derive strategy will also place a Copy
bound on type parameters:
;
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.
What's the difference between 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).
When can my type be Copy?
A type can implement Copy if all of its components implement Copy. For example, this
struct can be Copy:
#
A struct can be Copy, and i32 is Copy, therefore Point is eligible to be Copy.
By contrast, consider
#
# ;
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:
#
# ;
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.
When should my type be 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.
Additional implementors
In addition to the implementors listed below,
the following types also implement Copy:
- Function item types (i.e., the distinct types defined for each function)
- Function pointer types (e.g.,
fn() -> i32) - Closure types, if they capture no value from the environment
or if all such captured values implement
Copythemselves. Note that variables captured by shared reference always implementCopy(even if the referent doesn't), while variables captured by mutable reference never implementCopy.
Implementors
impl Copy for Alignmentimpl Copy for Alignmentimpl Copy for AlignmentEnumimpl Copy for AllocErrorimpl Copy for AlwaysEscapedimpl Copy for AsciiCharimpl Copy for Assumeimpl Copy for BiasedFpimpl Copy for CharCaseimpl Copy for CharErrorKindimpl Copy for CharTryFromErrorimpl Copy for CodePointimpl Copy for CodePointInnerimpl Copy for CpuidResultimpl Copy for DebugAsHeximpl Copy for Decimalimpl Copy for Decodedimpl Copy for DriftsortRunimpl Copy for Durationimpl Copy for Emptyimpl Copy for Errorimpl Copy for ErrorKindimpl Copy for FieldIdimpl Copy for FormattingOptionsimpl Copy for Fpimpl Copy for FpCategoryimpl Copy for FromBytesUntilNulErrorimpl Copy for FromBytesWithNulErrorimpl Copy for FullDecodedimpl Copy for HvxVectorimpl Copy for HvxVectorimpl Copy for HvxVectorPairimpl Copy for HvxVectorPairimpl Copy for HvxVectorPredimpl Copy for HvxVectorPredimpl Copy for I32NotAllOnesimpl Copy for I64NotAllOnesimpl Copy for IntErrorKindimpl Copy for IpAddrimpl Copy for Ipv4Addrimpl Copy for Ipv6Addrimpl Copy for Ipv6MulticastScopeimpl Copy for Layoutimpl Copy for Localityimpl Copy for MaybeEscapedimpl Copy for Nanosecondsimpl Copy for NonZeroCharInnerimpl Copy for NonZeroI128Innerimpl Copy for NonZeroI16Innerimpl Copy for NonZeroI32Innerimpl Copy for NonZeroI64Innerimpl Copy for NonZeroI8Innerimpl Copy for NonZeroIsizeInnerimpl Copy for NonZeroU128Innerimpl Copy for NonZeroU16Innerimpl Copy for NonZeroU32Innerimpl Copy for NonZeroU64Innerimpl Copy for NonZeroU8Innerimpl Copy for NonZeroUsizeInnerimpl Copy for Orderingimpl Copy for Orderingimpl Copy for PhantomPinnedimpl Copy for Rangeimpl Copy for RangeFullimpl Copy for RawWakerVTableimpl Copy for ResumeTyimpl Copy for SearchStepimpl Copy for SeekFromimpl Copy for Signimpl Copy for Signimpl Copy for Sinkimpl Copy for SocketAddrimpl Copy for SocketAddrV4impl Copy for SocketAddrV6impl Copy for Spanimpl Copy for Stateimpl Copy for TryFromCharErrorimpl Copy for TryFromIntErrorimpl Copy for TryFromSliceErrorimpl Copy for TypeIdimpl Copy for U32NotAllOnesimpl Copy for U64NotAllOnesimpl Copy for UsizeNoHighBitimpl Copy for Utf8Errorimpl Copy for VaListInnerimpl Copy for VariantIdimpl Copy for __m128impl Copy for __m128bhimpl Copy for __m128dimpl Copy for __m128himpl Copy for __m128iimpl Copy for __m256impl Copy for __m256bhimpl Copy for __m256dimpl Copy for __m256himpl Copy for __m256iimpl Copy for __m512impl Copy for __m512bhimpl Copy for __m512dimpl Copy for __m512himpl Copy for __m512iimpl Copy for __tile1024iimpl Copy for bf16impl Copy for boolimpl Copy for charimpl Copy for f128impl Copy for f16impl Copy for f16x2impl Copy for f32impl Copy for f64impl Copy for float16x4_timpl Copy for float16x4x2_timpl Copy for float16x4x3_timpl Copy for float16x4x4_timpl Copy for float16x8_timpl Copy for float16x8x2_timpl Copy for float16x8x3_timpl Copy for float16x8x4_timpl Copy for float32x2_timpl Copy for float32x2x2_timpl Copy for float32x2x3_timpl Copy for float32x2x4_timpl Copy for float32x4_timpl Copy for float32x4x2_timpl Copy for float32x4x3_timpl Copy for float32x4x4_timpl Copy for float64x1_timpl Copy for float64x1x2_timpl Copy for float64x1x3_timpl Copy for float64x1x4_timpl Copy for float64x2_timpl Copy for float64x2x2_timpl Copy for float64x2x3_timpl Copy for float64x2x4_timpl Copy for i128impl Copy for i16impl Copy for i32impl Copy for i64impl Copy for i8impl Copy for int16x4_timpl Copy for int16x4x2_timpl Copy for int16x4x3_timpl Copy for int16x4x4_timpl Copy for int16x8_timpl Copy for int16x8x2_timpl Copy for int16x8x3_timpl Copy for int16x8x4_timpl Copy for int32x2_timpl Copy for int32x2x2_timpl Copy for int32x2x3_timpl Copy for int32x2x4_timpl Copy for int32x4_timpl Copy for int32x4x2_timpl Copy for int32x4x3_timpl Copy for int32x4x4_timpl Copy for int64x1_timpl Copy for int64x1x2_timpl Copy for int64x1x3_timpl Copy for int64x1x4_timpl Copy for int64x2_timpl Copy for int64x2x2_timpl Copy for int64x2x3_timpl Copy for int64x2x4_timpl Copy for int8x16_timpl Copy for int8x16x2_timpl Copy for int8x16x3_timpl Copy for int8x16x4_timpl Copy for int8x8_timpl Copy for int8x8x2_timpl Copy for int8x8x3_timpl Copy for int8x8x4_timpl Copy for iovecimpl Copy for isizeimpl Copy for m128impl Copy for m128dimpl Copy for m128iimpl Copy for m256impl Copy for m256dimpl Copy for m256iimpl Copy for neverimpl Copy for nxv2i16impl Copy for nxv2i32impl Copy for nxv2i8impl Copy for nxv2u16impl Copy for nxv2u32impl Copy for nxv2u8impl Copy for nxv4i16impl Copy for nxv4i8impl Copy for nxv4u16impl Copy for nxv4u8impl Copy for nxv8i8impl Copy for nxv8u8impl Copy for poly16x4_timpl Copy for poly16x4x2_timpl Copy for poly16x4x3_timpl Copy for poly16x4x4_timpl Copy for poly16x8_timpl Copy for poly16x8x2_timpl Copy for poly16x8x3_timpl Copy for poly16x8x4_timpl Copy for poly64x1_timpl Copy for poly64x1x2_timpl Copy for poly64x1x3_timpl Copy for poly64x1x4_timpl Copy for poly64x2_timpl Copy for poly64x2x2_timpl Copy for poly64x2x3_timpl Copy for poly64x2x4_timpl Copy for poly8x16_timpl Copy for poly8x16x2_timpl Copy for poly8x16x3_timpl Copy for poly8x16x4_timpl Copy for poly8x8_timpl Copy for poly8x8x2_timpl Copy for poly8x8x3_timpl Copy for poly8x8x4_timpl Copy for svbool2_timpl Copy for svbool4_timpl Copy for svbool8_timpl Copy for svbool_timpl Copy for svfloat32_timpl Copy for svfloat32x2_timpl Copy for svfloat32x3_timpl Copy for svfloat32x4_timpl Copy for svfloat64_timpl Copy for svfloat64x2_timpl Copy for svfloat64x3_timpl Copy for svfloat64x4_timpl Copy for svint16_timpl Copy for svint16x2_timpl Copy for svint16x3_timpl Copy for svint16x4_timpl Copy for svint32_timpl Copy for svint32x2_timpl Copy for svint32x3_timpl Copy for svint32x4_timpl Copy for svint64_timpl Copy for svint64x2_timpl Copy for svint64x3_timpl Copy for svint64x4_timpl Copy for svint8_timpl Copy for svint8x2_timpl Copy for svint8x3_timpl Copy for svint8x4_timpl Copy for svpatternimpl Copy for svprfopimpl Copy for svuint16_timpl Copy for svuint16x2_timpl Copy for svuint16x3_timpl Copy for svuint16x4_timpl Copy for svuint32_timpl Copy for svuint32x2_timpl Copy for svuint32x3_timpl Copy for svuint32x4_timpl Copy for svuint64_timpl Copy for svuint64x2_timpl Copy for svuint64x3_timpl Copy for svuint64x4_timpl Copy for svuint8_timpl Copy for svuint8x2_timpl Copy for svuint8x3_timpl Copy for svuint8x4_timpl Copy for u128impl Copy for u16impl Copy for u32impl Copy for u64impl Copy for u8impl Copy for uint16x4_timpl Copy for uint16x4x2_timpl Copy for uint16x4x3_timpl Copy for uint16x4x4_timpl Copy for uint16x8_timpl Copy for uint16x8x2_timpl Copy for uint16x8x3_timpl Copy for uint16x8x4_timpl Copy for uint32x2_timpl Copy for uint32x2x2_timpl Copy for uint32x2x3_timpl Copy for uint32x2x4_timpl Copy for uint32x4_timpl Copy for uint32x4x2_timpl Copy for uint32x4x3_timpl Copy for uint32x4x4_timpl Copy for uint64x1_timpl Copy for uint64x1x2_timpl Copy for uint64x1x3_timpl Copy for uint64x1x4_timpl Copy for uint64x2_timpl Copy for uint64x2x2_timpl Copy for uint64x2x3_timpl Copy for uint64x2x4_timpl Copy for uint8x16_timpl Copy for uint8x16x2_timpl Copy for uint8x16x3_timpl Copy for uint8x16x4_timpl Copy for uint8x8_timpl Copy for uint8x8x2_timpl Copy for uint8x8x3_timpl Copy for uint8x8x4_timpl Copy for usizeimpl Copy for v128impl Copy for vector_bool_charimpl Copy for vector_bool_charimpl Copy for vector_bool_intimpl Copy for vector_bool_intimpl Copy for vector_bool_longimpl Copy for vector_bool_long_longimpl Copy for vector_bool_shortimpl Copy for vector_bool_shortimpl Copy for vector_doubleimpl Copy for vector_doubleimpl Copy for vector_floatimpl Copy for vector_floatimpl Copy for vector_signed_charimpl Copy for vector_signed_charimpl Copy for vector_signed_intimpl Copy for vector_signed_intimpl Copy for vector_signed_longimpl Copy for vector_signed_long_longimpl Copy for vector_signed_shortimpl Copy for vector_signed_shortimpl Copy for vector_unsigned_charimpl Copy for vector_unsigned_charimpl Copy for vector_unsigned_intimpl Copy for vector_unsigned_intimpl Copy for vector_unsigned_longimpl Copy for vector_unsigned_long_longimpl Copy for vector_unsigned_shortimpl Copy for vector_unsigned_shortimpl<'a> Copy for Argument<'a>impl<'a> Copy for ArgumentType<'a>impl<'a> Copy for Arguments<'a>impl<'a> Copy for IoSlice<'a>impl<'a> Copy for IoSlice<'a>impl<'a> Copy for Location<'a>impl<'a> Copy for Part<'a>impl<'a> Copy for PhantomContravariantLifetime<'a>impl<'a> Copy for PhantomCovariantLifetime<'a>impl<'a> Copy for PhantomInvariantLifetime<'a>impl<'a> Copy for Utf8Pattern<'a>impl<B: Copy, C: Copy> Copy for ControlFlow<B, C>impl<Dyn: PointeeSized> Copy for DynMetadata<Dyn>impl<F: Copy> Copy for RepeatWith<F>impl<Idx: Copy> Copy for Range<Idx>impl<Idx: Copy> Copy for RangeFrom<Idx>impl<Idx: Copy> Copy for RangeInclusive<Idx>impl<Idx: Copy> Copy for RangeTo<Idx>impl<Idx: Copy> Copy for RangeToInclusive<Idx>impl<Idx: Copy> Copy for RangeToInclusive<Idx>impl<K: Copy, V: Copy> Copy for KeyAndValue<K, V>impl<P: Copy + ?Sized> Copy for MaybeDangling<P>impl<Ptr: Copy> Copy for Pin<Ptr>impl<T> Copy for Discriminant<T>impl<T> Copy for NonZero<T> where T: ZeroablePrimitive,impl<T> Copy for PhantomContravariant<T> where T: ?Sized,impl<T> Copy for PhantomCovariant<T> where T: ?Sized,impl<T> Copy for PhantomInvariant<T> where T: ?Sized,impl<T> Copy for SyncView<T> where T: Sync + Copy,impl<T, const N: usize> Copy for Mask<T, N> where T: MaskElement,impl<T, const N: usize> Copy for Simd<T, N> where T: SimdElement,impl<T: ?Sized, const VARIANT: u32, const FIELD: u32> Copy for FieldRepresentingType<T, VARIANT, FIELD>impl<T: Copy + ?Sized> Copy for ManuallyDrop<T>impl<T: Copy + SimdElement, const N: usize> Copy for Simd<T, N>impl<T: Copy + SimdElement, const N: usize> Copy for SimdM<T, N>impl<T: Copy> Copy for Bound<T>impl<T: Copy> Copy for Complex<T>impl<T: Copy> Copy for MaybeUninit<T>impl<T: Copy> Copy for Option<T>impl<T: Copy> Copy for Poll<T>impl<T: Copy> Copy for RepeatNInner<T>impl<T: Copy> Copy for Reverse<T>impl<T: Copy> Copy for Saturating<T>impl<T: Copy> Copy for Wrapping<T>impl<T: Copy, E: Copy> Copy for Result<T, E>impl<T: Copy, const N: usize> Copy for [T; N]impl<T: PointeeSized> Copy for &Timpl<T: PointeeSized> Copy for *const Timpl<T: PointeeSized> Copy for *mut Timpl<T: PointeeSized> Copy for NonNull<T>impl<T: PointeeSized> Copy for PhantomData<T>impl<T: PointeeSized> Copy for Unique<T>impl<Y: Copy, R: Copy> Copy for CoroutineState<Y, R>impl<const N: usize> Copy for MaybeEscapedCharacter<N>