跳转到内容

第 5 章 函数与结构体

在前两章中,我们拆解了语言内置与标准库提供的核心类型构造器(引用、数组、切片、Vec<T> 与字符串)。从这一章开始,我们进入自定义类型与业务建模——看如何定义自己的函数与复合数据结构。

习惯了面向对象语言(如 Java 或 C++)的开发者,在初次接触 Rust 的函数和结构体时,往往会遇到三个直观的差异:

  • 为什么 Rust 没有 void 关键字,而且函数最后一行多打一个分号 ; 就会导致编译报错?
  • 为什么定义一个 struct 只有光秃秃的字段,既没有对象头,默认也不能按位复制(Copy),甚或把其中一个字段移走后,剩下的字段还能继续单独访问?
  • 为什么 Rust 的方法没有隐式的 this 指针,而是必须在第一个参数位置显式写出 &self、&mut self 或 self?

这一章分三步把「函数、结构体与方法」的底层机制串成闭环:

  • 第一步:函数、元组与表达式控制流——确立函数签名作为跨函数类型与所有权校验边界的地位;看清空元组 ()(单元类型,占 0 字节)如何统一取代 void,理解末尾分号 ; 如何把产出值的表达式变成返回 () 的语句,以及为什么 if / else 和代码块 {} 本身都能算出确定类型的值。
  • 第二步:结构体(struct)与部分移动(Partial Move)——掌握具名字段结构体、元组结构体与 0 字节单元结构体的定义与扁平内联内存布局;理解为什么自定义结构体默认一律走移动语义(需显式标注 #[derive(Clone, Copy)]),并拆解移出单个字段后编译器在字段粒度上的部分移动追踪规则。
  • 第三步:方法接收者三件套与调用点自动解引用——通过 impl 块将行为挂载到类型上,区分关联函数(::)与方法(.);看清 &self、&mut self、self 如何直接对应只读借用、独占可变借用与所有权消费,以及编译器在 . 调用点自动补齐 &、&mut 与 * 的规则与安全边界。

读完这一章,你应该能够回答以下三个问题:

  1. 表达式与语句的分界:函数体或 if / else 分支末尾加不加分号 ;,对求值产出的类型有什么影响?
  2. 字段级的所有权状态:当结构体中的某个非 Copy 字段被移走后,原结构体变量整体、被移走的字段以及其余未移动的字段分别处于什么可用状态?
  3. 方法接收者如何选型:在设计结构体方法或审查代码时,什么时候用 &self、什么时候用 &mut self、什么时候应该用按值消费的 self?