news 2026/6/13 14:52:09

RUST是移动语义与copy trait

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
RUST是移动语义与copy trait

在 Rust 中,实现了 Copy trait 的类型会被自动复制而不是移动。这些类型通常具有以下特点:

  1. 大小固定且在编译时已知

  2. 数据完全存储在栈上

  3. 浅复制和深复制效果相同

  4. 基本类型(Primitive Types)

所有基本类型都实现了 Copy:

fnmain(){// 整数类型letx:i8=1;lety:u8=2;leta:i16=3;letb:u16=4;letc:i32=5;// 默认整数类型letd:u32=6;lete:i64=7;letf:u64=8;letg:i128=9;leth:u128=10;leti:isize=11;// 平台相关,指针大小letj:usize=12;// 平台相关,指针大小// 浮点数类型letk:f32=3.14;letl:f64=2.718;// 默认浮点数类型// 布尔类型letm:bool=true;// 字符类型letn:char='🦀';// 所有这些类型都实现了 Copyletx2=x;// 复制,不是移动println!("{} {}",x,x2);// 两者都有效}
  1. 复合类型(Compound Types)

某些复合类型也实现了 Copy:

fnmain(){// 元组:当所有元素都实现 Copy 时lett1:(i32,f64)=(42,3.14);lett2=t1;// 复制println!("{:?} {:?}",t1,t2);// 两者都有效// 数组:当元素类型实现 Copy 且大小固定时letarr1:[i32;3]=[1,2,3];letarr2=arr1;// 复制println!("{:?} {:?}",arr1,arr2);// 以下会编译错误,因为 String 没有实现 Copy// let bad_tuple: (String, i32) = ("hello".to_string(), 42);// let bad_tuple2 = bad_tuple; // 错误:String 没有实现 Copy}
  1. 自定义类型的 Copy 实现

3.1 自动派生 Copy

#[derive(Copy, Clone, Debug)]structPoint{x:i32,y:i32,}#[derive(Copy, Clone, Debug)]structColor{r:u8,g:u8,b:u8,a:u8,}fnmain(){letp1=Point{x:10,y:20};letp2=p1;// 复制,因为 Point 实现了 Copyprintln!("p1: {:?}",p1);// 仍然有效println!("p2: {:?}",p2);letc1=Color{r:255,g:0,b:0,a:255};letc2=c1;// 复制println!("c1: {:?}",c1);println!("c2: {:?}",c2);}

3.2 不能自动实现 Copy 的情况

// 以下类型不能实现 Copy:// 1. 包含非 Copy 类型// 2. 可变引用// 3. 堆分配的类型#[derive(Debug)]structPerson{name:String,// String 没有实现 Copyage:u8,}implCloneforPerson{fnclone(&self)->Self{Person{name:self.name.clone(),// 需要显式克隆age:self.age,// u8 是 Copy,自动复制}}}// 不能派生 Copy,因为包含 String// #[derive(Copy, Clone)] // 编译错误!fnmain(){letp1=Person{name:"Alice".to_string(),age:30,};letp2=p1.clone();// 必须显式克隆// let p3 = p1; // 这是移动,p1 不再有效}
  1. Copy 与 Clone 的区别
#[derive(Debug)]structExample{data:i32,}implCloneforExample{fnclone(&self)->Self{println!("克隆被调用!");Example{data:self.data}}}// 实现 Copy 需要先实现 CloneimplCopyforExample{}fndemonstrate_copy_vs_clone(){lete1=Example{data:42};// Copy 类型:自动复制lete2=e1;// 这里调用的是 Copy,不是 Cloneprintln!("e1: {:?}, e2: {:?}",e1,e2);// 显式调用 clone 方法lete3=e1.clone();// 这里会调用 Cloneprintln!("e3: {:?}",e3);}fnmain(){demonstrate_copy_vs_clone();}
  1. Copy trait 的约束

要为一个类型实现 Copy,必须满足以下条件:

  1. 类型的所有字段都必须实现 Copy
  2. 类型不能实现 Drop trait
#[derive(Debug)]structNonCopyable{data:Vec<i32>,// Vec 没有实现 Copy}// 下面的实现会导致编译错误:// impl Copy for NonCopyable {} // 错误:NonCopyable 包含非 Copy 字段#[derive(Debug)]structResource{id:i32,}implDropforResource{fndrop(&mutself){println!("释放资源 {}",self.id);}}// 下面的实现会导致编译错误:// impl Copy for Resource {} // 错误:Resource 实现了 Drop
  1. 完整示例:自定义 Copy 类型
usestd::fmt;#[derive(Debug, Copy, Clone)]structComplex{real:f64,imag:f64,}implComplex{fnnew(real:f64,imag:f64)->Self{Complex{real,imag}}fnadd(self,other:Complex)->Complex{Complex{real:self.real+other.real,imag:self.imag+other.imag,}}}implfmt::DisplayforComplex{fnfmt(&self,f:&mutfmt::Formatter)->fmt::Result{write!(f,"{:.2} + {:.2}i",self.real,self.imag)}}fnmain(){letc1=Complex::new(1.0,2.0);letc2=Complex::new(3.0,4.0);// 由于 Complex 实现了 Copy,这里都是复制letc3=c1;letc4=c2;letsum=c3.add(c4);println!("c1 = {} (仍然有效)",c1);println!("c2 = {} (仍然有效)",c2);println!("c3 = {}",c3);println!("c4 = {}",c4);println!("c1 + c2 = {}",sum);}
  1. 判断类型是否实现 Copy
fnis_copy<T:Copy>(){println!("类型 T 实现了 Copy");}fncheck_types(){// 检查各种类型is_copy::<i32>();// ✓is_copy::<f64>();// ✓is_copy::<bool>();// ✓is_copy::<char>();// ✓is_copy::<(i32,f64)>();// ✓is_copy::<[i32;5]>();// ✓// 下面的会编译错误:// is_copy::<String>(); // ✗// is_copy::<Vec<i32>>(); // ✗// is_copy::<&mut i32>(); // ✗}fnmain(){check_types();}
  1. 在泛型中约束 Copy
// 泛型函数,要求 T 实现 Copyfnduplicate<T:Copy>(value:T)->(T,T){(value,value)}// 另一种写法fnduplicate2<T>(value:T)->(T,T)whereT:Copy,{(value,value)}fnmain(){// 这些调用都正常let(a1,a2)=duplicate(42);let(b1,b2)=duplicate(3.14);let(c1,c2)=duplicate('x');println!("{} {}",a1,a2);println!("{} {}",b1,b2);println!("{} {}",c1,c2);// 下面的调用会编译错误:// let s = String::from("hello");// let (s1, s2) = duplicate(s); // 错误:String 没有实现 Copy}
  1. Copy 类型列表总结

类别 具体类型 说明
整数 i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize 所有整数类型
浮点数 f32, f64 所有浮点数类型
布尔 bool 布尔值
字符 char Unicode 标量值
元组 (T1, T2, …) 当所有元素都实现 Copy 时
数组 [T; N] 当 T 实现 Copy 且 N 是编译时常量时
指针 *const T, *mut T 原始指针(不安全)
函数指针 fn(T1, T2) -> R 函数指针
空类型 () 单元类型

  1. 重要例外

以下类型没有实现 Copy:

fnmain(){// 1. String(堆分配)lets=String::from("hello");// let s2 = s; // 移动,不是复制// 2. Vec<T>(堆分配)letv=vec![1,2,3];// let v2 = v; // 移动// 3. Box<T>(堆分配)letb=Box::new(42);// let b2 = b; // 移动// 4. &mut T(可变引用)letmutx=5;letr=&mutx;// let r2 = r; // 移动// 5. Rc<T>, Arc<T>(引用计数)usestd::rc::Rc;letrc=Rc::new(42);// let rc2 = rc; // 移动(增加引用计数)}

关键记忆点:

  1. 所有基本类型(整数、浮点数、布尔、字符)都实现 Copy
  2. 堆分配的类型(String, Vec, Box)通常不实现 Copy
  3. 要自动派生 Copy,类型的所有字段都必须实现 Copy
  4. 实现了 Drop trait 的类型不能实现 Copy
  5. Copy 是标记 trait,没有方法,它依赖于 Clone trait
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 21:15:41

Oracle数据库迁移

简单谈谈本人对Oracle数据库的理解 话不多说直接开始 第一步&#xff1a;将原始数据库导出 方式1&#xff08;推荐&#xff09;&#xff1a;使用Data Pump --创建文件路径 create or replace directory 路径名 as C:\backup --根据情况自定义--执行导出命令 expdp 用户名/密…

作者头像 李华
网站建设 2026/6/14 8:59:59

Java毕设项目:基于SpringBoot的高校学生奖项管理系统基于springboot高校奖助学金系统(源码+文档,讲解、调试运行,定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/6/12 16:53:55

Wan2.2-T2V-A14B支持剪纸艺术动态展开过程模拟

Wan2.2-T2V-A14B支持剪纸艺术动态展开过程模拟 在数字内容创作的浪潮中&#xff0c;我们正见证一场从“静态图像”到“动态叙事”的跃迁。过去需要数小时手工拍摄、后期合成的传统艺术表现形式&#xff0c;如今只需一句话——比如&#xff1a;“一张红色宣纸缓缓展开&#xff0…

作者头像 李华
网站建设 2026/6/13 2:52:45

12.电阻电容电感选型

一、电阻 1、选型依据 阻值:电阻值; 封装:常用封装0201,0402,0603,0805,1206,1812等&#xff1b; 功耗:1/16W,1/10W,1/8W,1/4W,1/2W,1W,2W,3W等&#xff1b; 精度:1%&#xff0c;5%等。 2、选型方法 ①、优先考虑阻值&#xff0c;对于不常见的阻值&#xff0c;可以通过电阻的…

作者头像 李华
网站建设 2026/6/13 21:56:38

Vue 项目实战,从组件缓存到 Vant UI 集成:项目初始化全流程

Vue 项目开发中&#xff0c;组件缓存能提升页面性能&#xff0c;项目初始化&#xff08;ESLint、目录结构、路由&#xff09;是工程化的基础&#xff0c;而Vant UI是移动端开发的常用组件库。 一、组件缓存&#xff1a;提升页面性能的关键 组件缓存通过<keep-alive>标签实…

作者头像 李华
网站建设 2026/6/13 12:32:35

约翰·博格尔的长期投资回报预测模型

约翰博格尔的长期投资回报预测模型 关键词&#xff1a;约翰博格尔、长期投资回报预测模型、投资分析、市场回报、股息收益 摘要&#xff1a;本文深入探讨了约翰博格尔的长期投资回报预测模型。该模型在投资领域具有重要地位&#xff0c;能够帮助投资者对长期投资回报进行合理预…

作者头像 李华