Skip to content

函数 ​

在 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. 参考 ​