这一章,我将通过生活化的比喻和例子,帮助各位小伙伴轻松理解 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)------真正放进锅里的蛋。
举个栗子:
rustfn 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
是表达式,没有分号,所以它被返回。
错误示范:加了分号就变"语句",不返回值!
rustfn 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() |
记住三句话
fn
开头,()
参数,{}
包住菜谱。- 语句做事不返回,表达式计算出结果。
- 函数最后一行无分号,默默返回值;加了分号变语句,返回
()
空盘子。