解除引用时Rust是否自动实现克隆? #[派生(调试)] 结构点{ x:i32, y:i32, } 点{}的impl复制 点的impl克隆{ fn克隆(&self)->点{ *自我 } }

解除引用时Rust是否自动实现克隆? #[派生(调试)] 结构点{ x:i32, y:i32, } 点{}的impl复制 点的impl克隆{ fn克隆(&self)->点{ *自我 } },rust,Rust,当我只实现Copy时,Rust告诉我需要实现Clone。当我只实现克隆时,Rust告诉我可以移动点 我的问题是,我从来没有实现过任何东西,这段代码有点像一个循环依赖,但它能工作吗?为什么?TL;DR:Copy为方便起见需要Clone,而Copy类型上的Clone通常使用副本实现 Rust编译器通常必须对数据进行逐位复制。但有两种情况: 如果类型未实现Copy,则原始实例不再可用,您的数据已移动 如果类型实现了Copy,编译器知道继续使用原始实例和新实例是完全安全的 Copy特性不会改变编译

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


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

TL;DR:
Copy
为方便起见需要
Clone
,而
Copy
类型上的
Clone
通常使用副本实现


Rust编译器通常必须对数据进行逐位复制。但有两种情况:

  • 如果类型未实现
    Copy
    ,则原始实例不再可用,您的数据已移动
  • 如果类型实现了
    Copy
    ,编译器知道继续使用原始实例和新实例是完全安全的
Copy
特性不会改变编译器只会自动执行逐位复制的事实:它是一种没有方法的标记特性。它的工作只是告诉编译器“在按位复制后继续使用它是可以的”

克隆
特征并没有那么特别:它是一种常规特征,有一种方法可以做任何你想让它做的事情。编译器从不自动使用
克隆
特性,也不关心它的实际功能。但是,它显然是为了创建实例的克隆,因此以下操作完全正常:

  • 期望
    Copy
    类型实现
    Clone
    。毕竟,
    Copy
    Clone
    更严格的版本。这就是为什么
    Copy:Clone
    必须在
    Copy
    类型上实现
    Clone
  • 复制
    类型上的
    克隆
    应该是哑的,并且只执行逐位复制。你不会希望这里有两种不同的语义,那会很混乱。这就是为什么在您的示例中,
    clone
    使用一个简单的
    *self
    实现的原因:这会取消对
    self
    的引用,从而导致逐位复制
然而,手动实现这些特性是非常罕见的,大多数情况下,您只需使用
派生

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

这不是一个循环依赖,但它可能确实有点令人惊讶。考虑启用。生锈永远不会自动克隆。