当前位置: 首页 > news >正文

06_ownership——所有权的使用

两端代码思考与对比

  • 答案①:
pub fn title(self) -> String {
self.title
}Copy codepub fn description(self) -\> String {self.description}pub fn status(self) -\> String {self.status}
  • 答案②:
pub fn title(&self) -> &str {&self.title}pub fn description(&self) -> &str {&self.description}pub fn status(&self) -> &str {&self.status}

两段代码虽然都能通过编译,但答案②才是正确做法

对比分析:

维度 方案一 方案二
能否编译
能否通过测试
性能 ❌每次调用都转移所有权 ✅ 零成本借用
可用性 ❌只能调用一次 ✅ 可以多次调用
内存消耗 ❌消耗对象 ✅ 不消耗对象
rust惯用法 ❌不符合 ✅ 标准getter模式

问题演示

  • 为什么方案一可以通过代码测试?
    测试代码:
#[test]
fn title() {let ticket = Ticket::new("A title".into(), "A description".into(), "To-Do".into());assert_eq!(ticket.title(), "A title");// 测试到此结束,ticket 被消耗了也无所谓
}

每个测试都是独立的,只调用一次 getter,所以代码能通过
但在真实场景中:

// 使用方案一
let ticket = Ticket::new("标题".into(), "描述".into(), "To-Do".into());let t = ticket.title();  // ← ticket 被消耗(move)
// let d = ticket.description();  // ❌ 编译错误!ticket 已经不存在了
// 使用方案二
let ticket = Ticket::new("标题".into(), "描述".into(), "To-Do".into());let t = ticket.title();        // ✅ 借用
let d = ticket.description();  // ✅ 还能用
let s = ticket.status();       // ✅ 还能用// 甚至可以多次访问同一个字段
for _ in 0..10 {println!("{}", ticket.title());  // ✅ 可以循环调用
}

性能对比

  • 方案一:
pub fn title(self) -> String {self.title  // 转移所有权,整个 Ticket 对象被销毁
}// 调用成本:
// 1. 转移整个 Ticket 结构体(包括 3 个 String)
// 2. 提取 title 字段
// 3. 销毁剩余字段(description 和 status 被 drop)
// 4. 返回 String
  • 方案二:
pub fn title(&self) -> &str {&self.title  // 只是返回一个指针
}// 调用成本:
// 1. 传递一个引用(8 字节指针)
// 2. 返回一个切片引用(16 字节:指针 + 长度)
// 零堆分配,零复制
  • 测试
// 方案一
let ticket = create_ticket();
let _ = ticket.title();  // 消耗整个对象
// 成本:~100-200 纳秒(取决于字符串长度)// 方案二
let ticket = create_ticket();
let _ = ticket.title();  // 只是借用
let _ = ticket.title();  // 可以继续用
// 成本:~1-5 纳秒(几乎零成本)

Getter 方法的设计原则

Rust社区的最佳实践:

// ✅ 标准 getter 模式
pub fn field(&self) -> &FieldType {&self.field
}// ❌ 反模式:消耗对象的 getter
pub fn field(self) -> FieldType {self.field
}// ⚠️ 可接受但不推荐:克隆数据
pub fn field(&self) -> FieldType {self.field.clone()
}

补充:什么时候用self(消耗对象)
只有明确知道self会被消耗,在转换方法中使用,通常命名into_xxx

http://www.jsqmd.com/news/422083/

相关文章:

  • Spring Bean销毁机制
  • OpenCV DNN + ONNX 跨框架实时推理实战:PyTorch/TF模型导出ONNX后用OpenCV DNN加速,CPU/GPU实时目标检测
  • CF1034D
  • 使用 Typer + Pydantic + Rich 快速打造企业级 Python 命令行工具
  • 未来之窗昭和仙君(七十六)扫码支付查询函数—东方仙盟练气
  • 为量子互联网“掐表”:基于ZYNQ的皮秒级TDC与自适应温漂补偿系统实战
  • 使用 Rich 库打造专业 CLI 工具:终端美化、Table、Progress、Syntax 高亮、Theme 自定义与 Live 动态 UI 实
  • ionic 列表:全面解析与实战指南
  • QA之二 - 单元测试-- JaCoCo
  • 基于YOLO+deepseek 智慧农业作物长势监测系统 | 基于YOLO+deepseek 人脸识别与管理系统
  • 程序员兼职怎么选到更靠谱的软件外包平台
  • 谷歌NanoBanana 2又刷屏了,一文看懂如何使用
  • 闲置分某乐微信立减金回收方式推荐,高效转化闲置资源 - 京顺回收
  • 2026省选集训比赛总结
  • 校招/社招通用!计算机信息类专业简历写法,面试官一眼看中
  • 别再让AI毁网站了!告别蓝紫渐变,这7招彻底去除AI味,新手也能会 踩坑无数总结的去AI味技巧|从请求者变指挥官,AI做站也能有质感
  • JVM内存模型详解与垃圾回收日志分析
  • 中年不发福的关键!8个好习惯,不用节食,腰腹慢慢变紧致
  • 春节回来,康复学习Day4(13:30-18:00)
  • 使用Sentinel作为Spring Boot应用限流组件
  • 谷歌最新Nano Banana 2模型发布!国内免费使用教程
  • 算法:两个链表的第一个公共节点。
  • python生成静音音频
  • TCP 粘包与 UDP 丢包
  • PyTorch中的memory format - NCHW和channels last
  • YOLO26改进46:全网首发--使用FSConv改进下采样
  • abc447
  • 北京五粮液上门回收|经典五粮液、老五粮液、原件五粮液,上门高价收 - 品牌排行榜单
  • OpenClaw 源码深度解析(一):Gateway——为什么需要一个“中枢“
  • 北京茅台上门回收|年份茅台、生肖茅台、飞天茅台,当场结算不压价 - 品牌排行榜单