【问题标题】:Does Rust automatically implement clone when dereference?取消引用时,Rust 会自动实现克隆吗?
【发布时间】:2020-07-21 11:40:49
【问题描述】:
#[derive(Debug)]
struct Point {
    x: i32,
    y: i32,
}

impl Copy for Point {}

impl Clone for Point {
    fn clone(&self) -> Point {
        *self
    }
}

当我只实现 Copy 时,Rust 告诉我需要实现 Clone。当我只实现Clone 时,Rust 告诉我Point 可以移动。

我的问题是,我从来没有实现过任何东西,这段代码有点像循环依赖,但它有效吗?为什么?

【问题讨论】:

  • 它不是循环依赖,但确实可能有点令人惊讶。考虑启用this Clippy lint
  • Rust 永远不会自动克隆。

标签: rust


【解决方案1】:

TL;DR:为了方便,Copy 需要 CloneClone 上的 Copy 类型通常使用副本实现。


Rust 编译器通常必须按位复制您的数据。但有两种情况:

  • 如果类型实现Copy,则原始实例不再可用,您的数据已移动
  • 如果该类型确实实现了Copy,编译器就知道继续使用原始实例和新实例是完全安全的。

Copy trait 不会改变编译器只会自动进行逐位复制的事实:它是一个没有方法的标记 trait。它的工作只是告诉编译器“在按位复制后可以继续使用它”。

Clone trait 并没有那么特别:它是一个常规的 trait,它的方法可以为所欲为。编译器从不自动使用 Clone 特征,也不关心它实际上做了什么。然而,它显然是为了创建一个实例的克隆,所以这是完全正常的:

  • 期望Copy 类型实现Clone。毕竟CopyClone的更严格的版本。这就是为什么 Copy: Clone 并且您必须在 Copy 类型上实现 Clone 的原因。
  • 期望Copy 类型上的Clone 是哑的并且只执行按位复制。你不会在这里想要两种不同的语义,那会很混乱。这就是为什么 clone 在您的示例中使用简单的 *self 实现的原因:这会取消引用 self,这会导致按位复制。

然而,手动实现这些 trait 是非常少见的,而且大多数时候,你只会选择derive

#[derive(Copy, Clone, Debug)]
struct Point {
    x: i32,
    y: i32,
}

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 2014-10-04
    • 1970-01-01
    • 2015-03-24
    • 2016-06-01
    • 2017-09-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-06
    相关资源
    最近更新 更多