代码之家  ›  专栏  ›  技术社区  ›  sdgfsdh

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

  •  12
  • sdgfsdh  · 技术社区  · 8 年前

    the book :

    Rust不会让我们用 Copy 如果类型或其任何部分实现了 Drop 特质。如果类型需要在值超出范围时发生特殊情况,并且我们添加 复制 对于该类型的注释,我们将得到一个编译时错误。

    为什么设计决定不允许 复制 下降 在同一类型上?

    2 回复  |  直到 8 年前
        1
  •  15
  •   Boiethios    8 年前
    • 这个 Drop 特征用于 RAII 上下文,通常在销毁对象时需要释放/关闭某些资源时。
    • 另一方面,a Copy 类型是可以用 memcpy 只有。

    有了这两种描述,就更清楚了,它们是排他性的:没有意义 记忆 非平凡数据:如果我们复制数据,然后删除其中一个副本,会怎么样?另一个副本的内部资源将不再可靠。

    事实上, 复制 即使是“真实”的特质,也无法定义任何功能。这是特别的 标记 这对编译器说:“你可以用一个简单的字节拷贝来复制我自己”。所以您不能提供 复制 ,因为根本没有实现。但是,可以将类型标记为可复制:

    impl Copy for Foo {}
    

    或者更好的是,有一个派生:

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

    只有当所有字段都实现 复制 . 否则,编译器将拒绝编译,因为这是不安全的。


    举个例子,假设 File 结构实现 复制 . 当然,这是 这个例子是错误的,无法编译:

    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();
    }
    
        2
  •  4
  •   hellow Adolfo Casari    8 年前

    引用 documentation .

    […][A]ny类型实现 Drop 不可能是 Copy ,因为它在管理自己的资源之外 size_of::<T> 字节。

    推荐文章