本文简要介绍rust语言中 Trait core::marker::Copy 的用法。
用法
pub trait Copy: Clone { }可以简单地通过复制位来复制其值的类型。
默认情况下,变量绑定有 'move semantics.' 换句话说:
#[derive(Debug)]
struct Foo;
let x = Foo;
let y = x;
// `x` has moved into `y`, and so cannot be used
// println!("{:?}", x); // error: use of moved value但是,如果一个类型实现了 Copy ,则它改为具有 'copy semantics':
// We can derive a `Copy` implementation. `Clone` is also required, as it's
// a supertrait of `Copy`.
#[derive(Debug, Copy, Clone)]
struct Foo;
let x = Foo;
let y = x;
// `y` is a copy of `x`
println!("{:?}", x); // A-OK!需要注意的是,在这两个示例中,唯一的区别是是否允许您在分配后访问x。在幕后,复制和移动都可能导致位被复制到内存中,尽管有时这会被优化掉。
如何实现 Copy ?
有两种方法可以在您的类型上实现Copy。最简单的是使用 derive :
#[derive(Copy, Clone)]
struct MyStruct;您还可以手动实现Copy 和Clone:
struct MyStruct;
impl Copy for MyStruct { }
impl Clone for MyStruct {
fn clone(&self) -> MyStruct {
*self
}
}两者之间有一个小小的区别:derive 策略还将在类型参数上放置 Copy 绑定,但这并不总是需要的。
Copy 和 Clone 有什么区别?
复制是隐式发生的,例如作为分配 y = x 的一部分。 Copy 的行为不可重载;它总是一个简单的按位复制。
克隆是一个显式操作,x.clone()。 Clone 的实现可以提供安全复制值所需的任何 type-specific 行为。例如 String 的 Clone 的实现需要复制堆中指向的字符串缓冲区。 String 值的简单按位复制只会复制指针,从而导致双倍释放。因此, String 是 Clone 但不是 Copy 。
Clone 是 Copy 的超特征,因此 Copy 的所有内容也必须实现 Clone 。如果一个类型是Copy,那么它的 Clone 实现只需要返回*self(见上面的例子)。
我的类型什么时候可以是 Copy ?
如果一个类型的所有组件都实现了Copy,则该类型可以实现Copy。例如,这个结构可以是 Copy :
#[derive(Copy, Clone)]
struct Point {
x: i32,
y: i32,
}结构可以是 Copy ,而 i32 是 Copy ,因此 Point 有资格成为 Copy 。相比之下,考虑
struct PointList {
points: Vec<Point>,
}结构 PointList 无法实现 Copy ,因为 Vec<T> 不是 Copy 。如果我们尝试派生 Copy 实现,我们会得到一个错误:
the trait `Copy` may not be implemented for this type; field `points` does not implement `Copy`共享参考 (&T) 也是Copy, 所以一个类型可以是Copy,即使它拥有类型的共享引用T那是不是 Copy.考虑以下结构,它可以实现Copy, 因为它只持有一个共享参考对我们的非Copy类型PointList从上面:
#[derive(Copy, Clone)]
struct PointListWrapper<'a> {
point_list_ref: &'a PointList,
}什么时候不能我的类型是Copy?
某些类型无法安全复制。例如,复制 &mut T 将创建一个别名可变引用。复制 String 将重复管理 String 缓冲区的责任,从而导致双重释放。
概括后一种情况,任何实现 Drop 的类型都不能是 Copy ,因为它除了自己的 size_of::<T> 字节之外还管理一些资源。
如果您尝试在包含非 Copy 数据的结构或枚举上实现 Copy ,您将收到错误 E0204 。
什么时候应该我的类型是Copy?
一般来说,如果您的类型能够实施Copy, 它应该。但请记住,实施Copy是您的类型的公共 API 的一部分。如果该类型可能变为非Copy将来,谨慎的做法可能是省略Copy现在实施,以避免重大 API 更改。
其他实现者
除了下面列出的实现者之外,以下类型还实现 Copy :
- 函数项类型(即为每个函数定义的不同类型)
- 函数指针类型(例如,
fn() -> i32) - 元组类型,如果每个组件也实现
Copy(例如,(),(i32, bool)) - 闭包类型,如果它们没有从环境中捕获任何值,或者所有这些捕获的值都实现了
Copy。请注意,共享引用捕获的变量始终实现Copy(即使引用对象没有),而可变引用捕获的变量从不实现Copy。
相关用法
- Rust Condvar.notify_all用法及代码示例
- Rust Command.args用法及代码示例
- Rust Condvar.wait用法及代码示例
- Rust Cow.is_owned用法及代码示例
- Rust Cow用法及代码示例
- Rust Condvar.wait_timeout用法及代码示例
- Rust Condvar.wait_timeout_while用法及代码示例
- Rust Command.env用法及代码示例
- Rust Command.env_remove用法及代码示例
- Rust Command.get_args用法及代码示例
- Rust Command.stdout用法及代码示例
- Rust Command.stdin用法及代码示例
- Rust Components用法及代码示例
- Rust Component.as_os_str用法及代码示例
- Rust ControlFlow用法及代码示例
- Rust Command.current_dir用法及代码示例
- Rust Command.output用法及代码示例
- Rust ControlFlow.break_value用法及代码示例
- Rust Command.status用法及代码示例
- Rust Cow.into_owned用法及代码示例
- Rust Condvar.wait_while用法及代码示例
- Rust Command.envs用法及代码示例
- Rust Command用法及代码示例
- Rust Command.get_program用法及代码示例
- Rust Command.arg用法及代码示例
注:本文由纯净天空筛选整理自rust-lang.org大神的英文原创作品 Trait core::marker::Copy。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。
