Skip to content

参数与返回值

> 学习函数参数的类型标注规则,掌握单返回值、多返回值(元组)的写法。

参数详解

参数必须标注类型

rust
// ✅ 正确:参数类型明确
fn add(x: i32, y: i32) -> i32 {
    x + y
}

// ❌ 错误:Rust 无法推断参数类型
// fn add(x, y) -> i32 {
//     x + y
// }
▶ Run

为什么 Rust 要求参数标注类型?

Rust 的类型推断是"局部的":
┌─────────────────────────────────────────┐
│ • 编译器从右向左推断类型                  │
│ • 参数在函数体之前,无法从使用处推断     │
│ • 这样做编译更快,错误信息更清晰         │
└─────────────────────────────────────────┘

多个参数

rust
fn print_person_info(name: &str, age: u8, city: &str, hobby: &str) {
    println!("姓名:{}", name);
    println!("年龄:{} 岁", age);
    println!("城市:{}", city);
    println!("爱好:{}", hobby);
}

fn main() {
    // 参数按顺序传递
    print_person_info("张三", 25, "北京", "编程");

    // 参数类型必须匹配
    // print_person_info("张三", "二十五", "北京", "编程");  // ❌ 错误
}
▶ Run

参数命名规范

rust
fn main() {
    // ✅ 蛇形命名(snake_case)- Rust 约定
    fn calculate_total_price(base_price: f64, tax_rate: f64) -> f64 {
        base_price * (1.0 + tax_rate)
    }

    // ❌ 不推荐:驼峰命名
    fn calculateTotalPrice(basePrice: f64, taxRate: f64) -> f64 {
        basePrice * (1.0 + taxRate)
    }

    // ✅ 有意义的名字
    fn calculate_area(width: f64, height: f64) -> f64 {
        width * height
    }

    // ❌ 无意义的名字
    fn calc(w: f64, h: f64) -> f64 {
        w * h
    }
}
▶ Run

返回值详解

表达式 vs 语句(重要!)

这是 Rust 与其他语言的关键区别:

rust
fn main() {
    // 语句(Statement):执行操作,不返回值
    let x = 5;           // let 绑定是语句
    x = x + 1;           // 赋值是语句
    println!("x = {}", x);  // 函数调用是语句

    // 表达式(Expression):计算并返回值
    let y = {            // {} 块是表达式
        let a = 3;
        let b = 5;
        a + b            // 没有分号!这是返回值 ←
    };                   // y = 8

    println!("y = {}", y);

    // if 是表达式(可以返回值)
    let condition = true;
    let number = if condition { 5 } else { 6 };
    println!("number = {}", number);
}
▶ Run

返回值规则

rust
// 规则:函数体最后一个表达式(无分号)作为返回值

fn add(x: i32, y: i32) -> i32 {
    x + y  // 没有分号,是表达式,返回值
}

fn main() {
    let result = add(3, 5);
    println!("3 + 5 = {}", result);  // 8
}
▶ Run

使用 return 关键字

rust
fn main() {
    // 通常不需要 return(使用表达式返回)
    fn add(x: i32, y: i32) -> i32 {
        x + y
    }

    // 使用 return 的情况:提前返回
    fn find_first_even(numbers: &[i32]) -> i32 {
        for &n in numbers {
            if n % 2 == 0 {
                return n;  // 提前返回
            }
        }
        -1  // 没找到返回 -1
    }

    let nums = [1, 3, 5, 8, 10];
    println!("第一个偶数:{}", find_first_even(&nums));  // 8
}
▶ Run

无返回值(单元类型 ())

rust
fn main() {
    // 没有返回类型的函数,实际上返回 ()
    fn say_hello() {
        println!("Hello!");
        // 隐式返回 ()
    }

    // 显式返回 ()
    fn say_goodbye() -> () {
        println!("Goodbye!");
        ()  // 显式返回单元值
    }

    // 验证返回类型
    let result = say_hello();
    println!("返回值:{:?}", result);  // ()

    let result2 = say_goodbye();
    println!("返回值:{:?}", result2);  // ()
}
▶ Run

小结

  • 每个参数都必须显式标注类型,不能省略
  • 多返回值通过元组实现:fn foo() -> (i32, &str)
  • 无返回值的函数隐式返回 ()(单元类型)
  • 函数签名是代码的自文档,清晰的类型标注提升可读性

练习题

详见:练习题