为什么 Rust 不允许在一种类型上复制和删除特征?

2024-05-08

From the book https://doc.rust-lang.org/book/2018-edition/ch04-01-what-is-ownership.html#stack-only-data-copy:

Rust 不允许我们用Copy如果类型或其任何部分已经实现了特征Drop特征。如果当值超出范围时类型需要发生一些特殊的事情并且我们添加Copy如果对该类型进行注释,我们将收到编译时错误。

为什么设计决定不允许Copy and Drop在同一类型上?


  • The Drop特征用于RAII https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization上下文,通常是在对象被销毁时需要释放/关闭某些资源时。
  • 另一方面,一个Copytype 是一个简单的类型,可以用memcpy only.

通过这两个描述,可以更清楚地看出它们是排他性的:没有意义memcpy非平凡数据:如果我们复制数据并删除其中一个副本怎么办?另一个副本的内部资源将不再可靠。

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

impl Copy for Foo {}

或者更好的是,使用派生:

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

仅当所有字段都实现时才会构建Copy。否则,编译器将拒绝编译,因为这是不安全的。


为了举例,我们假设File结构实现Copy。当然,这是not这种情况,这个例子是错误的,无法编译:

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();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 Rust 不允许在一种类型上复制和删除特征? 的相关文章

随机推荐