趣味学Rust基础篇(函数)

这一章,我将通过生活化的比喻和例子,帮助各位小伙伴轻松理解 Rust 函数的核心概念,各位读者就当做是看小说一般。


用"菜谱"理解 Rust 函数:从零开始做一道菜

假设你现在是一位非常有名的厨师,而 Rust 的函数(function)就是你的菜谱。每道菜都有名字、步骤、需要的食材(参数),最后做出一道美味的菜(返回值)。咱们就用这个"厨房哲学"来聊聊 Rust 的函数怎么玩。

1. 函数长什么样?------ fn 是你的厨师帽

在 Rust 里,定义一个函数就像戴上厨师帽,喊一声:"我要开始做菜了!"

rust 复制代码
fn main() {
    println!("Hello, world!");

    another_function();
}

fn another_function() {
    println!("Another function.");
}
  • fn 就是"function"的缩写,意思是"我要写个菜谱了"。
  • another_function() 就像喊服务员:"上菜!"------这就是调用函数
  • 函数名用蛇形命名法(snake_case) :全小写,单词之间用下划线 _ 连接,比如 make_pizza()wash_dishes(),就像菜名一样清晰。

小知识:main 函数是"主菜",程序一启动就从它开始,就像餐厅开门第一道招牌菜。


2. 参数:你的"食材清单"

做菜得有食材,函数也一样。这些"食材"就叫参数(parameters)

比如你想做"煎蛋",但煎几个蛋?用什么油?这些就是参数。

rust 复制代码
fn main() {
    fry_eggs(3); // 我要煎 3 个蛋!
}

fn fry_eggs(eggs: i32) {
    println!("煎了 {eggs} 个蛋,香喷喷!");
}
  • eggs: i32 表示"需要一个叫 eggs 的整数(i32)作为食材"。
  • 当你调用 fry_eggs(3)3 就是实参(argument)------真正放进锅里的蛋。

举个栗子:

rust 复制代码
fn make_coffee(sugar: i32, milk: bool) {
    println!("加了 {sugar} 勺糖,牛奶:{milk}");
}

调用 make_coffee(2, true),就做出一杯"2 勺糖 + 牛奶"的咖啡。


3. 语句 vs 表达式:指令 vs 计算结果

这是 Rust 最容易搞混的点,但用厨房比喻就秒懂!

语句(Statements):做事,但不返回结果

就像厨房里的"指令":

  • "把鸡蛋打在碗里" (做了事,但没产出新东西)
  • "把锅烧热"

在代码里:

rust 复制代码
let x = 6; // 这是一条"指令":把 6 放进变量 x 的碗里

这是一条语句,它不返回任何值。你不能写:

rust 复制代码
let y = (let x = 6); //  错!就像说"把'打蛋'这个动作放进另一个碗"------没意义!

Rust 和 C/Python 不同:赋值不返回值 。所以 x = y = 5 在 Rust 里是非法的。

表达式(Expressions):计算,得出一个结果

表达式就像"算账"或"混合食材":

  • 5 + 6 是表达式,结果是 11
  • fry_eggs(2) 是表达式,结果是"一盘煎蛋"
  • { } 花括号包起来的代码块也是表达式!
rust 复制代码
let total = {
    let x = 3;
    x + 1 // 注意:这里没有分号!
};
// total 的值是 4!因为整个代码块"计算出"了 4

关键区别:

  • 有分号 ; → 语句 (不返回值,类型是 (),读作"单元类型")
  • 无分号 → 表达式(返回值)

4. 返回值:最后端上桌的那道菜

函数可以"做菜",也可以"上菜"。这个"菜"就是返回值

在 Rust 里,函数默认返回最后一个表达式的值 ,不需要写 return(除非你想提前退出)。

rust 复制代码
fn give_me_five() -> i32 {
    5 // 直接写 5,它就是"菜",端上桌!
}

fn main() {
    let x = give_me_five(); // x 得到 5
    println!("x 是 {x}"); // 输出:x 是 5
}
  • -> i32 表示"这道菜是 i32 类型的整数"。
  • 5 是表达式,没有分号,所以它被返回。

错误示范:加了分号就变"语句",不返回值!

rust 复制代码
fn plus_one(x: i32) -> i32 {
    x + 1; // 加了分号,变成语句,返回 (),但函数声明要 i32 → 报错!
}

编译器会说:"你承诺上 i32 的菜,结果端了个空盘子 (),骗子!"

综合实战:做一个"自动售货机"函数

rust 复制代码
fn vend_snack(money: i32) -> String {
    if money >= 5 {
        "薯片一包!".to_string() // 表达式,返回
    } else {
        "钱不够,买不起!".to_string()
    }
    // 没有分号!整个 if 是表达式,返回其中一个字符串
}

fn main() {
    let snack = vend_snack(10);
    println!("{snack}"); // 输出:薯片一包!
}

if 语句块本身也可以是表达式!只要里面是表达式且没有分号,就能返回值。


总结:函数就像菜谱

厨房术语 Rust 对应 例子
菜名 函数名 fn make_tea() fn make_tea()
食材 参数 water: i32, sugar: i32 fn make_tea(water: i32, sugar: i32)
步骤 语句 let cup = 0; let cup = 0;
混合调料 表达式 sugar + salt sugar + salt
上菜 返回值 -> String "茶好了!".to_string()

记住三句话

  1. fn 开头,() 参数,{} 包住菜谱。
  2. 语句做事不返回,表达式计算出结果。
  3. 函数最后一行无分号,默默返回值;加了分号变语句,返回 () 空盘子。