Trait std::marker::Copy

1.0.0 · source ·
pub trait Copy: Clone { }
Expand description

只需复制位即可复制其值的类型。

默认情况下,变量绑定具有移动语义。换句话说:

#[derive(Debug)]
struct Foo;

let x = Foo;

let y = x;

// `x` 已移入 `y`,因此无法使用

// println!("{x:?}"); // error: use of moved value
Run

但是,如果类型实现 Copy,则它具有复制语义:

// 我们可以派生一个 `Copy` 实现。
// `Clone` 也是必需的,因为它是 `Copy` 的 super trait。
#[derive(Debug, Copy, Clone)]
struct Foo;

let x = Foo;

let y = x;

// `y` 是 `x` 的副本

println!("{x:?}"); // A-OK!
Run

重要的是要注意,在这两个示例中,唯一的区别是分配后是否允许您访问 x。 在后台,复制和移动都可能导致将位复制到内存中,尽管有时会对其进行优化。

如何实现 Copy

有两种方法可以在您的类型上实现 Copy。最简单的是使用 derive

#[derive(Copy, Clone)]
struct MyStruct;
Run

您还可以手动实现 CopyClone

struct MyStruct;

impl Copy for MyStruct { }

impl Clone for MyStruct {
    fn clone(&self) -> MyStruct {
        *self
    }
}
Run

这两者之间有一个小小的区别: derive 策略还将 Copy 绑定在类型参数上,这并不总是需要的。

CopyClone 有什么区别?

Copy 是隐式发生的,例如作为赋值 y = x 的一部分。Copy 的行为不可重载; 它始终是简单的按位复制。

Clone 是一个显式操作,x.clone()Clone 的实现可以提供安全复制值所需的任何特定于类型的行为。 例如,用于 StringClone 的实现需要在堆中复制指向字符串的缓冲区。 String 值的简单按位副本将仅复制指针,从而导致该行向下双重释放。 因此,StringClone,但不是 Copy

CloneCopy 的一个 super trait,所以所有 Copy 的东西也必须实现 Clone。 如果类型为 Copy,则其 Clone 实现仅需要返回 *self (请参见上面的示例)。

什么时候可以输入 Copy

如果类型的所有组件都实现 Copy,则它可以实现 Copy。例如,此结构体可以是 Copy

#[derive(Copy, Clone)]
struct Point {
   x: i32,
   y: i32,
}
Run

一个结构体可以是 Copy,而 i32Copy,因此 Point 有资格成为 Copy。 相比之下,考虑

struct PointList {
    points: Vec<Point>,
}
Run

结构体 PointList 无法实现 Copy,因为 Vec<T> 不是 Copy。如果尝试派生 Copy 实现,则会收到错误消息:

the trait `Copy` cannot be implemented for this type; field `points` does not implement `Copy`

共享引用 (&T) 也是 Copy,因此,即使类型中包含 04 不是*Copy 类型的共享引用 T,也可以是 Copy。 考虑下面的结构体,它可以实现 Copy,因为它从上方仅对我们的非 Copy 类型 PointList 持有一个 shared 引用

#[derive(Copy, Clone)]
struct PointListWrapper<'a> {
    point_list_ref: &'a PointList,
}
Run

什么时候我的类型不能为 Copy

某些类型无法安全复制。例如,复制 &mut T 将创建一个别名可变引用。 复制 String 将重复管理 String 缓冲区,从而导致双重释放。

概括后一种情况,任何实现 Drop 的类型都不能是 Copy,因为它除了管理自己的 size_of::<T> 字节外还管理一些资源。

果您尝试在包含非 Copy 数据的结构或枚举上实现 Copy,则会收到 E0204 错误。

什么时候我的类型应该是 Copy

一般来说,如果您的类型可以实现 Copy,则应该这样做。 但是请记住,实现 Copy 是您类型的公共 API 的一部分。 如果该类型将来可能变为非 Copy,则最好现在省略 Copy 实现,以避免 API 发生重大更改。

其他实现者

下面列出的实现者 之外,以下类型也实现了 Copy

  • 函数项类型 (即,为每个函数定义的不同类型)
  • 函数指针类型 (例如 fn() -> i32)
  • 闭包类型,如果它们没有从环境中捕获任何值,或者所有此类捕获的值本身都实现了 Copy。 请注意,由共享引用捕获的变量始终实现 Copy (即使引用对象没有实现),而由变量引用捕获的变量从不实现 Copy

Implementors§

source§

impl Copy for AsciiChar

source§

impl Copy for std::cmp::Ordering

1.34.0 · source§

impl Copy for Infallible

1.28.0 · source§

impl Copy for std::fmt::Alignment

source§

impl Copy for ErrorKind

source§

impl Copy for SeekFrom

1.7.0 · source§

impl Copy for IpAddr

source§

impl Copy for Ipv6MulticastScope

source§

impl Copy for Shutdown

source§

impl Copy for SocketAddr

source§

impl Copy for FpCategory

source§

impl Copy for BacktraceStyle

source§

impl Copy for Which

source§

impl Copy for SearchStep

source§

impl Copy for std::sync::atomic::Ordering

1.12.0 · source§

impl Copy for RecvTimeoutError

source§

impl Copy for TryRecvError

source§

impl Copy for bool

source§

impl Copy for char

source§

impl Copy for f32

source§

impl Copy for f64

source§

impl Copy for i8

source§

impl Copy for i16

source§

impl Copy for i32

source§

impl Copy for i64

source§

impl Copy for i128

source§

impl Copy for isize

source§

impl Copy for !

source§

impl Copy for u8

source§

impl Copy for u16

source§

impl Copy for u32

source§

impl Copy for u64

source§

impl Copy for u128

source§

impl Copy for ()

source§

impl Copy for usize

1.27.0 · source§

impl Copy for CpuidResult

1.27.0 · source§

impl Copy for __m128

source§

impl Copy for __m128bh

1.27.0 · source§

impl Copy for __m128d

1.27.0 · source§

impl Copy for __m128i

1.27.0 · source§

impl Copy for __m256

source§

impl Copy for __m256bh

1.27.0 · source§

impl Copy for __m256d

1.27.0 · source§

impl Copy for __m256i

source§

impl Copy for __m512

source§

impl Copy for __m512bh

source§

impl Copy for __m512d

source§

impl Copy for __m512i

source§

impl Copy for TimSortRun

source§

impl Copy for AllocError

source§

impl Copy for Global

1.28.0 · source§

impl Copy for Layout

1.28.0 · source§

impl Copy for System

source§

impl Copy for TypeId

1.34.0 · source§

impl Copy for TryFromSliceError

1.34.0 · source§

impl Copy for CharTryFromError

1.59.0 · source§

impl Copy for TryFromCharError

source§

impl Copy for Error

source§

impl Copy for FileTimes

1.1.0 · source§

impl Copy for FileType

source§

impl Copy for Empty

source§

impl Copy for Sink

source§

impl Copy for Assume

source§

impl Copy for Ipv4Addr

source§

impl Copy for Ipv6Addr

source§

impl Copy for SocketAddrV4

source§

impl Copy for SocketAddrV6

1.34.0 · source§

impl Copy for NonZeroI8

1.34.0 · source§

impl Copy for NonZeroI16

1.34.0 · source§

impl Copy for NonZeroI32

1.34.0 · source§

impl Copy for NonZeroI64

1.34.0 · source§

impl Copy for NonZeroI128

1.34.0 · source§

impl Copy for NonZeroIsize

1.28.0 · source§

impl Copy for NonZeroU8

1.28.0 · source§

impl Copy for NonZeroU16

1.28.0 · source§

impl Copy for NonZeroU32

1.28.0 · source§

impl Copy for NonZeroU64

1.28.0 · source§

impl Copy for NonZeroU128

1.28.0 · source§

impl Copy for NonZeroUsize

1.34.0 · source§

impl Copy for TryFromIntError

source§

impl Copy for RangeFull

source§

impl Copy for UCred

Available on Unix only.
1.61.0 · source§

impl Copy for ExitCode

source§

impl Copy for ExitStatus

source§

impl Copy for ExitStatusError

source§

impl Copy for std::ptr::Alignment

source§

impl Copy for Utf8Error

source§

impl Copy for RecvError

1.5.0 · source§

impl Copy for WaitTimeoutResult

1.36.0 · source§

impl Copy for RawWakerVTable

1.26.0 · source§

impl Copy for AccessError

1.19.0 · source§

impl Copy for ThreadId

1.3.0 · source§

impl Copy for Duration

1.8.0 · source§

impl Copy for Instant

1.8.0 · source§

impl Copy for SystemTime

1.33.0 · source§

impl Copy for PhantomPinned

source§

impl<'a> Copy for Component<'a>

source§

impl<'a> Copy for Prefix<'a>

source§

impl<'a> Copy for Arguments<'a>

1.36.0 · source§

impl<'a> Copy for IoSlice<'a>

1.10.0 · source§

impl<'a> Copy for Location<'a>

1.28.0 · source§

impl<'a> Copy for Ancestors<'a>

source§

impl<'a> Copy for PrefixComponent<'a>

source§

impl<'a, T, const N: usize> Copy for ArrayWindows<'a, T, N>where T: Copy + 'a,

1.63.0 · source§

impl<'fd> Copy for BorrowedFd<'fd>

1.63.0 · source§

impl<'handle> Copy for BorrowedHandle<'handle>

Available on Windows only.
1.63.0 · source§

impl<'socket> Copy for BorrowedSocket<'socket>

Available on Windows only.
1.55.0 · source§

impl<B, C> Copy for ControlFlow<B, C>where B: Copy, C: Copy,

source§

impl<Dyn> Copy for DynMetadata<Dyn>where Dyn: ?Sized,

1.28.0 · source§

impl<F> Copy for RepeatWith<F>where F: Copy,

source§

impl<Idx> Copy for RangeTo<Idx>where Idx: Copy,

1.26.0 · source§

impl<Idx> Copy for RangeToInclusive<Idx>where Idx: Copy,

1.33.0 · source§

impl<P> Copy for Pin<P>where P: Copy,

source§

impl<Ret, T> Copy for fn (T₁, T₂, …, Tₙ) -> Ret

这个 trait 是在具有任意数量参数的函数指针上实现的。

1.17.0 · source§

impl<T> Copy for Bound<T>where T: Copy,

source§

impl<T> Copy for Option<T>where T: Copy,

1.36.0 · source§

impl<T> Copy for Poll<T>where T: Copy,

source§

impl<T> Copy for *const Twhere T: ?Sized,

source§

impl<T> Copy for *mut Twhere T: ?Sized,

source§

impl<T> Copy for &Twhere T: ?Sized,

共享的引用可以复制,但是可变引用 不能!

1.19.0 · source§

impl<T> Copy for Reverse<T>where T: Copy,

1.21.0 · source§

impl<T> Copy for Discriminant<T>

1.20.0 · source§

impl<T> Copy for ManuallyDrop<T>where T: Copy + ?Sized,

source§

impl<T> Copy for Saturating<T>where T: Copy,

source§

impl<T> Copy for Wrapping<T>where T: Copy,

1.25.0 · source§

impl<T> Copy for NonNull<T>where T: ?Sized,

source§

impl<T> Copy for PhantomData<T>where T: ?Sized,

1.36.0 · source§

impl<T> Copy for MaybeUninit<T>where T: Copy,

source§

impl<T, E> Copy for Result<T, E>where T: Copy, E: Copy,

source§

impl<T, const LANES: usize> Copy for Mask<T, LANES>where T: MaskElement, LaneCount<LANES>: SupportedLaneCount,

1.58.0 · source§

impl<T, const N: usize> Copy for [T; N]where T: Copy,

source§

impl<T, const N: usize> Copy for Simd<T, N>where LaneCount<N>: SupportedLaneCount, T: SimdElement,

source§

impl<T: Copy> Copy for TrySendError<T>

source§

impl<T: Copy> Copy for (T₁, T₂, …, Tₙ)

这个 trait 在任意长度的元组上实现。

source§

impl<T: Copy> Copy for SendError<T>

source§

impl<Y, R> Copy for GeneratorState<Y, R>where Y: Copy, R: Copy,