Rust 中的 Copy 和 Clone 比较

在 Rust 中,CopyClone 控制着类型的复制行为。它们决定值如何被复制以及在何种情况下允许复制。本文将详细介绍这两个特性的用途和用法,并通过代码示例展示它们的使用。

Copy

Copy 是什么?

Copy 是一个标记特性,意味着它不定义任何方法。它只是标记一个类型可以进行复制。

rust 复制代码
#[derive(Copy)]
struct Point {
    x: i32,
    y: i32,
}

如何实现 Copy

要实现 Copy 特性,你需要在类型定义上添加 #[derive(Copy)] 属性。此外,类型还必须实现 Clone ,因为所有实现 Copy 的类型也必须实现 Clone

rust 复制代码
#[derive(Copy, Clone)]
struct Point {
    x: i32,
    y: i32,
}

如果你试图在没有实现 Clone 的情况下实现 Copy,编译器将抛出错误:

rust 复制代码
#[derive(Copy)]
struct Point {
    x: i32,
    y: i32,
}

// 错误:`Point` 类型不满足 `std::clone::Clone` 特性

错误信息表明 Point 类型没有实现 Clone 特性,因此不能实现 Copy

这一要求是因为所有 Copy 类型必须实现 Clone。当你显式调用 clone 方法时,Rust 假设你创建一个副本,并希望复制行为是明确定义的。因此,你想实现 Copy,你也必须实现 Clone

哪些类型可以实现 Copy

并非所有类型都能实现 Copy。只有符合以下标准的类型才有资格:

  • 类型本身是 普通旧数据(POD) 类型,即不包含任何指针或引用。
  • 类型的所有字段也必须实现 Copy

例如,以下类型 无法 实现 Copy,因为它包含一个引用字段:

rust 复制代码
struct Foo<'a> {
    x: &'a i32,
}

// 错误:`Copy` 特性不能为这种类型实现
impl Copy for Foo<'_> {}

为什么我们需要 Copy 特性?

Copy 特性允许控制类型的复制行为。当一个类型实现了 Copy,它的值在赋值、作为函数参数传递和返回时会自动复制。这消除了显式调用 clone() 来复制值的需要。

此外,由于 Copy 类型总是进行按位复制,性能开销很小。这对于优化 Rust 程序的性能特别有用。

Clone 特性

Copy 不同,Clone 特性允许显式复制类型的值。当一个类型实现了 Clone,你可以调用它的 clone() 方法来创建一个新实例。

Clone 特性是什么?

Copy 不同,Clone 是一个包含方法的特性 。这个方法负责创建值的新副本。

rust 复制代码
#[derive(Clone)]
struct Point {
    x: i32,
    y: i32,
}

如何实现 Clone

要实现 Clone ,你可以添加 #[derive(Clone)] 属性,或者手动实现 clone() 方法。

rust 复制代码
#[derive(Clone)]
struct Point {
    x: i32,
    y: i32,
}

// 手动实现 `clone()` 方法
impl Clone for Point {
    fn clone(&self) -> Self {
        Self { x: self.x, y: self.y }
    }
}

哪些类型可以实现 Clone

几乎所有的类型都可以实现 Clone 。只要你能定义一个值的新副本,你就可以实现 Clone

为什么我们需要 Clone 特性?

Clone 特性允许显式复制值。这对于那些 无法 按位复制的类型特别有用,例如包含指针或引用的类型。

此外,Clone 允许自定义复制过程。你可以在 clone() 方法中添加任何必要的逻辑,在复制期间执行特定操作。

CopyClone 的区别和关系

CopyClone 都控制类型的复制方式,但它们有关键区别:

  • Copy 是一个 标记特性 ,表示一个类型支持按位复制。当一个类型实现了 Copy,它的值在赋值、作为函数参数传递和返回时会 自动 复制。
  • Clone 是一个 普通特性 ,包含一个方法:clone() 。当一个类型实现了 Clone,你可以 显式 调用 clone() 来创建新副本。

此外,所有 Copy 类型也必须实现 Clone 。这确保了当你显式调用 clone() 时,Rust 假设你知道自己在做什么,并允许按位复制。

示例分析

下面是一个展示 CopyClone 使用的示例:

rust 复制代码
#[derive(Copy, Clone)]
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let p1 = Point { x: 1, y: 2 };
    let p2 = p1; // 自动复制
    let p3 = p1.clone(); // 显式复制
}

在这个示例中,我们定义了一个 Point 类型,并实现了 CopyClone 特性。在 main 函数中,我们创建了一个 Point 值并将其赋值给另一个变量。由于 Point 实现了 Copy,赋值操作自动复制了值。此外,我们显式调用了 clone() 来创建值的另一个副本。

原文:www.yuque.com/fengjutian/... 《Rust 中的 Copy 和 Clone 比较》

相关推荐
utmhikari9 分钟前
【架构艺术】Go语言微服务monorepo的代码架构设计
后端·微服务·架构·golang·monorepo
蜡笔小新星12 分钟前
Flask项目框架
开发语言·前端·经验分享·后端·python·学习·flask
计算机学姐15 分钟前
基于Asp.net的驾校管理系统
vue.js·后端·mysql·sqlserver·c#·asp.net·.netcore
欢乐少年19042 小时前
SpringBoot集成Sentry日志收集-3 (Spring Boot集成)
spring boot·后端·sentry
浪九天6 小时前
Java直通车系列13【Spring MVC】(Spring MVC常用注解)
java·后端·spring
uhakadotcom7 小时前
Apache CXF 中的拒绝服务漏洞 CVE-2025-23184 详解
后端·面试·github
uhakadotcom7 小时前
CVE-2025-25012:Kibana 原型污染漏洞解析与防护
后端·面试·github
uhakadotcom7 小时前
揭秘ESP32芯片的隐藏命令:潜在安全风险
后端·面试·github
uhakadotcom7 小时前
Apache Camel 漏洞 CVE-2025-27636 详解与修复
后端·面试·github
uhakadotcom7 小时前
OpenSSH CVE-2025-26466 漏洞解析与防御
后端·面试·github