函数
在 Rust 中,函数是代码的基本构建块,用于封装可重用的逻辑。你已经写了很多函数,本课把定义规则系统化,并建立一个重要心智模型:语句与表达式的区分。
1. 基本语法
rust
fn 函数名(参数名: 类型, 参数名: 类型) -> 返回类型 {
// 函数体
// 最后一个表达式(无分号)作为返回值
}三种典型形态:
rust
// 无参数、无返回值
fn say_hello() {
println!("Hello!");
}
// 有参数、有返回值
fn add(a: i32, b: i32) -> i32 {
a + b // 隐式返回(无分号)
}
// 显式返回
fn max_of(a: i32, b: i32) -> i32 {
if a > b {
return a; // 提前返回
}
b // 隐式返回
}2. 关键规则
| 规则 | 说明 |
|---|---|
| 参数类型必须声明 | 函数签名是调用方看到的契约,编译器不做函数签名的类型推断 |
| 返回类型可选 | 无返回值时省略 -> 类型(相当于返回 ()) |
| 隐式返回 | 最后一个表达式(无分号)自动作为返回值 |
| 显式返回 | return 用于提前返回,配合分号 |
| 命名 | 蛇形小写(snake_case),动词开头表意:calculate_sum、process_data |
3. 语句与表达式:隐式返回的原理
函数体是一系列语句加一个可选的结尾表达式。二者区别:
- 语句:执行一个动作,不产生值。如
let x = 6; - 表达式:求值并产生一个结果。如
6、x + 1、函数调用、一个{}块
块本身也是表达式 —— 块中最后一条表达式(无分号)就是块的值:
rust
fn block_value() -> i64 {
let inner = {
let doubled = 4;
doubled * 10 // 这个块的值是 40,赋给了 inner
};
inner + 2 // 函数尾表达式:40 + 2
}由此得出函数返回值的完整规则:函数体结尾的表达式就是返回值。这就是 a + b(无分号)能返回值、而 a + b;(加分号变成语句)返回 () 的原因 —— 也是 clippy 报 needless_return 的原因:结尾的 return x; 与 x 完全等价,后者才是惯用写法。
推论:Rust 的 = 是语句而非表达式,因此不存在 C 风格的连等赋值:
rust
// let x = (let y = 6);return 的定位是提前返回:函数执行到 return 立即结束,后面代码不再执行。
4. 无返回值:单元类型 ()
rust
fn print_sum(a: i32, b: i32) {
println!("{}", a + b);
} // 等价于 -> ()调用它得到的"返回值"就是 ()(空元组),表示"没有值"。
5. 注释
三种形态:
rust
// 行注释:最常用
/*
块注释:可以跨行,实际很少用
*/
/// 文档注释:写在函数、结构体等定义的上方
/// 它不是给人看的普通注释 —— `cargo doc` 会把所有 /// 生成 HTML 文档网页,
/// 标准库官网文档就是由标准库源码中的 /// 生成的。
fn documented() {}文档注释里还可以写示例代码块,cargo test 会把它当测试执行(保证文档里的示例永远能跑通)。练习中的三个函数都要求写 ///,试一试。
6. 参考
- rustdoc 文档 —— 文档注释的生成工具