函数、参数与返回值
你会学到什么
- 函数参数必须写类型。
- 返回值类型写在
->后面。 - 没有分号的最后一个表达式会成为返回值。
最小示例
fn add(left: i32, right: i32) -> i32 {
left + right
}
left + right 后面没有分号,所以它是函数返回值。
运行代码
cd examples
cargo run -p rt_04_functions
cargo test -p rt_04_functions
代码讲解
Rust 可以使用 return 提前返回,但常规路径更推荐表达式风格:
fn is_passing(score: u32) -> bool {
score >= 60
}
函数签名是调用方和实现方之间的契约。参数和返回值类型清楚之后,编译器能在调用点提前发现错误。
常见错误
下面的函数会报错,因为分号把表达式变成了语句:
fn add(left: i32, right: i32) -> i32 {
left + right;
}
修复方式是去掉最后的分号。
练习
- 写一个
minutes_to_hours(minutes: u32) -> f64。 - 给函数增加单元测试。
小结
函数签名要显式,函数体可以保持表达式风格。理解分号是否存在非常重要。
下一步
下一章学习 if、loop、while 和 for。
完整示例代码
下面是 examples/04_functions/ 的完整源码。无需 clone 仓库,直接在页面上阅读、复制、对照运行。
examples/04_functions/src/main.rs
fn add(left: i32, right: i32) -> i32 {
left + right
}
fn rectangle_area(width: u32, height: u32) -> u32 {
width * height
}
fn passing_label(score: u32) -> &'static str {
if score >= 60 { "pass" } else { "retry" }
}
fn main() {
println!("2 + 3 = {}", add(2, 3));
println!("area = {}", rectangle_area(4, 6));
println!("score 88 => {}", passing_label(88));
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn adds_numbers() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn calculates_area() {
assert_eq!(rectangle_area(4, 6), 24);
}
#[test]
fn labels_passing_score() {
assert_eq!(passing_label(88), "pass");
assert_eq!(passing_label(59), "retry");
}
} examples/04_functions/Cargo.toml
[package]
name = "rt_04_functions"
version.workspace = true
edition.workspace = true
publish.workspace = true