为什么 Rust 不允许在一种类型上复制和删除特征? [英] Why does Rust not allow the copy and drop traits on one type?
问题描述
来自 这本书:
如果类型或其任何部分实现了 Drop
特征,Rust 不会让我们用 Copy
特征注释类型.如果该类型需要在值超出范围时发生特殊情况,并且我们向该类型添加 Copy
注释,我们将收到编译时错误.
Rust won’t let us annotate a type with the
Copy
trait if the type, or any of its parts, has implemented theDrop
trait. If the type needs something special to happen when the value goes out of scope and we add theCopy
annotation to that type, we’ll get a compile time error.
为什么设计决定不允许在同一类型上使用 Copy
和 Drop
?
Why was the design decision made to disallow Copy
and Drop
on the same type?
推荐答案
Drop
特性用于 RAII 上下文,通常当对象被销毁时需要释放/关闭某些资源时.- 另一方面,
Copy
类型是一种普通类型,只能使用memcpy
进行复制. - The
Drop
trait is used in an RAII context, typically when some resource needs to be released/closed when the object is destroyed. - In the other hand, a
Copy
type is a trivial type that can be copied with amemcpy
only.
通过这两个描述,更清楚的是它们是排他性的:memcpy
非平凡数据是没有意义的:如果我们复制数据,然后删除其中一个副本会怎样?另一个副本的内部资源将不再可靠.
With those two descriptions, it is clearer that they are exclusive: it makes no sense to memcpy
nontrivial data: what if we copy the data, and we drop one of the copies? The inner resource of the other copy will not be reliable anymore.
事实上,Copy
甚至不是真正的"特征,因为它没有定义任何函数.它是一个特殊的标记,它对编译器说:你可以用一个简单的字节副本来复制自己".所以你不能提供 Copy
的自定义实现,因为根本没有实现.但是,您可以将类型标记为可复制:
In fact, Copy
in not even a "real" trait, in that it does not define any function. It is a special marker that says to the compiler: "you can duplicate myself with a simple bytes copy". So you cannot provide a custom implementation of Copy
, because there is no implementation at all. However, you can mark a type as copyable:
impl Copy for Foo {}
或者更好,带有一个派生:
or better, with a derive:
#[derive(Clone, Copy)]
struct Foo { /* ... */ }
仅当所有字段都实现Copy
时才会构建.否则,编译器拒绝编译,因为这是不安全的.
This builds only if all the fields implement Copy
. Otherwise, the compiler refuses to compile because this is unsafe.
为了举例,我们假设 File
结构实现了 Copy
.当然,不是,这个例子是错误的,无法编译:
For the sake of an example, let's suppose that the File
struct implements Copy
. Of course, this is not the case, and this example is wrong and cannot compile:
fn drop_copy_type<T>(T x)
where
T: Copy + Drop,
{
// The inner file descriptor is closed there:
std::mem::drop(x);
}
fn main() {
let mut file = File::open("foo.txt").unwrap();
drop_copy_type(file);
let mut contents = String::new();
// Oops, this is unsafe!
// We try to read an already closed file descriptor:
file.read_to_string(&mut contents).unwrap();
}
这篇关于为什么 Rust 不允许在一种类型上复制和删除特征?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!