如何理解Rust中的对象

先看看下面2段代码,第1段代码正常,第2段却编译失败,为什么呢?

复制代码
fn main() {
    let a: u32 = 5;
    let b = a;
    
    println!("a={a}, b={b}");
}
 正常

fn main() {
    let a = String::from("Hello");
    let b = a;
    
    println!("a={a}, b={b}");
}
 编译失败

第2段代码的编译错误信息显示 a 的所有权已经被转移,那第1段代码为什么没有发生转移呢?直接的原因是u32 数据类型支持 Copy trait,而 String 数据类型不支持 Copy trait。

如何实现自定义数据类型支持Copy trait

  1. 如果自定义数据类型的所有成员类型都已经支持 Copy trait,直接在定义中使用继承宏即可。如代码 - 3,这里需要注意一点,支持 Copy 的前提是支持 Clone。

    #[derive(Debug, Clone, Copy)]
    struct ST {
    a: i32,
    b: u16,
    c: f32,
    d: [i8; 10]
    }
    fn main() {
    let a = ST{a:-32, b:17, c: 3.28, d:[80;10]};
    let b = a;

    复制代码
     println!("a={a:?}");
     println!("b={b:?}");

    }

  2. 如果自定义数据类型中有成员不支持 Copy trait,那么这个类型就无法支持 Copy trait。

一旦数据类型支持了 Copy trait,那么赋值语句就会隐式地重新生成一个对象,从而占用更多的内存。同时 Drop trait 和 Copy trait 是互斥的,无法同时支持。

如果强制将对象分配到堆上

多数 Rust 原型类型数据默认是分配在栈上的,比如 i32, u16 等等。那么如何才能将它们分配到堆上,从而使它跨越函数甚至线程来访问呢?

  1. 使用静态变量。这没什么好说的,但在很多情况下,不是好习惯。
  2. 使用 Box 来强制分配到堆上。

小结

在Rust中,对象是内存中的一个数据(大小不定)。内存对象大致分有2种情况:一种是对象全部在栈内存中,比如原生类型;另一种是对象实际上分成2个部分:实际数据内容位于堆内存上,而栈内存上有一个胖指针(指向起始位置的指针和数据长度)指向堆上的实际内容,代码通过这个胖指针访问实际数据,比如 String 类型。

对于第一种类型,赋值操作执行按位复制不会存在什么问题。对于第二种类型,如果赋值操作仅仅对栈部分执行按位复制就会造成多个胖指针指向同一个堆内容,在没有进入引用计数的情况下就容易造成悬垂指针的情况下,所以,对于第二种类型,Rust 的赋值操作执行的是移动语义,即转移所有权。

我们知道栈对象在函数返回时就会自动释放,但堆对象需要某种方式进行额外的释放操作,否则就存在内存泄漏问题。在Rust中,第二种类型对象,都默认实现了 Drop trait,进而在语音层面实现了安全释放的功能,即栈部分释放前,会调用 Drop::drop 来析构整个对象。

相关推荐
TunerT_TQ4 小时前
Valhalla 静态工程审阅 #007|AgentENV 源码证据驱动评测【大厂开源基础设施特辑】
rust·开源·go·github·sandbox·分布式系统·ai基础设施
NutShell Wang5 小时前
Vite 8.1 深度拆解:Rolldown 统一打包器如何终结前端构建的「双引擎时代」
前端·rust·开源·vite·开发者工具·vibe coding
寒水馨6 小时前
macOS下载、安装uv-0.12.0(附安装包uv-aarch64-apple-darwin.tar.gz)
python·macos·rust·项目管理·包管理器·astral·pip替代
寒水馨7 小时前
macOS下载、安装ripgrep-15.2.0(附安装包ripgrep-15.2.0-aarch64-apple-darwin.tar.gz)
macos·正则表达式·rust·ripgrep·rg·命令行搜索·代码搜索
SomeB1oody21 小时前
【RustyML入门】1.0. 快速上手
开发语言·后端·机器学习·rust·教程
骊城英雄21 小时前
Rust从入门到精通-trait
人工智能·算法·rust
花褪残红青杏小1 天前
Rust图像处理第23节-图像加噪:给每个像素单独掷一次骰子
rust·webassembly·图形学
小杍随笔1 天前
2025年Rust GUI框架实战万字避坑指南
开发语言·后端·rust
在水一缸2 天前
当 AI 编码助手遇上 Rust:深入解析 Zerostack 的极简哲学与实战应用
rust·系统架构·开源项目·轻量化·ai编码助手·zerostack
2401_873479402 天前
风控引擎高并发IP查询方案对比:开源Rust库 vs 商业离线库,怎么选?
tcp/ip·rust·开源·ip