the book开始:

如果一个类型或其任何部分实现了Drop特征,Rust将不允许我们用Copy特征对该类型进行注释.如果该类型在值超出范围时需要发生特殊情况,并且我们向该类型添加了Copy注释,那么我们将得到一个编译时错误.

为什么设计决定不允许在同一型号上使用CopyDrop

推荐答案

  • Drop特征用于RAII上下文中,通常是当对象被销毁时需要释放/关闭某些资源时.
  • 另一方面,Copy类型是一种普通类型,只能用memcpy复制.

有了这两种描述,就更清楚地表明它们是排他性的:memcpy个非平凡的数据毫无意义:如果我们复制数据,并删除其中一个副本,会怎么样?另一个副本的内部资源将不再可靠.

事实上,Copy甚至不是一个"真正的"特征,因为它没有定义任何功能.这是一个特殊的marker,它对编译器说:"你可以用一个简单的字节拷贝复制我自己".所以不能提供Copy的自定义实现,因为根本没有实现.但是,可以将类型标记为可复制:

impl Copy for Foo {}

或者更好,用一个派生词:

#[derive(Clone, Copy)]
struct Foo { /* ... */ }

只有当所有字段都实现Copy时,才会生成此函数.否则,编译器会拒绝编译,因为这是不安全的.


作为示例,我们假设File struct 实现Copy.当然,情况就是这样,这个例子是错误的,无法编译:

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相关问答推荐

如何在 struct 中填充缓冲区并同时显示它?

如何从使用mockall模拟的方法中返回self?

如何在Bevy/Rapier3D中获得碰撞机的计算质量?

为什么铁 rust S似乎有内在的易变性?

在使用AWS SDK for Rust时,如何使用硬编码访问密钥ID和密钥凭据?

重写Rust中的方法以使用`&;mut self`而不是`mut self`

对于已经被认为是未定义行为的相同数据,纯粹存在`&;[u32]`和`&;mut[u32]`吗?

完全匹配包含大小写的整数范围(&Q;)

在文件链实施中绕过borrow 判断器

如何使用Actix Web for Rust高效地为大文件服务

应为关联类型,找到类型参数

链表堆栈溢出

当我编译 Rust 代码时,我是否缺少 AVX512 的目标功能?

带引脚和不带引脚的比较功能

Rust 如何将链表推到前面?

部署Rust发布二进制文件的先决条件

在给定 Rust 谓词的情况下,将 Some 转换为 None 的惯用方法是什么?

当我在 struct 中存储异步函数时,为什么它需要生命周期

从函数返回 u32 的数组/切片

为什么这个闭包没有比 var 长寿?