函数与返回值
学习目标
- 掌握函数定义语法
- 理解参数和返回值
- 理解表达式 vs 语句
- 掌握提前返回和
return关键字
核心概念
函数定义
fn greet(name: &str) {
println!("Hello, {}!", name);
}
fn add(a: i32, b: i32) -> i32 {
a + b // 注意:没有分号 = 这是返回值表达式
}
命名规范:函数名用 snake_case(小写下划线)。
参数
fn describe(name: &str, age: u32, height: f64) {
println!("{} is {} years old, {:.1}m tall", name, age, height);
}
fn main() {
describe("Alice", 30, 1.65);
}
返回值
// 方式一:最后一个表达式(不加分号)—— 推荐
fn double(x: i32) -> i32 {
x * 2
}
// 方式二:显式 return —— 用于提前返回
fn find_first_negative(numbers: &[i32]) -> Option<i32> {
for &n in numbers {
if n < 0 {
return Some(n); // 提前返回
}
}
None
}
表达式 vs 语句
这是 Rust 的核心概念:
fn main() {
// 语句(statement):执行操作,不返回值
let x = 5; // let 语句
// 表达式(expression):产生值
5 // 字面量表达式
x + 1 // 算术表达式
{ // 块表达式
let y = 3;
y + 1 // 块的最后一个表达式是块的值
}
// ❌ 加了分号变成语句,没有返回值
let y = {
let x = 3;
x + 1; // 加了分号 → 语句 → 返回 ()
}; // y 的类型是 ()
}
多返回值(元组)
fn swap(a: i32, b: i32) -> (i32, i32) {
(b, a)
}
fn div_rem(a: i32, b: i32) -> (i32, i32) {
(a / b, a % b)
}
fn main() {
let (quotient, remainder) = div_rem(17, 5);
println!("17 / 5 = {} 余 {}", quotient, remainder);
}
永不返回的函数
fn forever() -> ! {
loop {
// 永远不会返回
}
}
fn exit_with_error(msg: &str) -> ! {
panic!("{}", msg); // panic! 返回类型是 !
}
实践练习
练习 1:温度转换函数
fn fahrenheit_to_celsius(f: f64) -> f64 {
(f - 32.0) * 5.0 / 9.0
}
fn celsius_to_fahrenheit(c: f64) -> f64 {
c * 9.0 / 5.0 + 32.0
}
fn main() {
let boiling_f = 212.0;
let boiling_c = fahrenheit_to_celsius(boiling_f);
println!("{}°F = {}°C", boiling_f, boiling_c);
let body_c = 37.0;
let body_f = celsius_to_fahrenheit(body_c);
println!("{}°C = {}°F", body_c, body_f);
}
练习 2:判断质数
fn is_prime(n: u32) -> bool {
if n < 2 {
return false;
}
let mut i = 2;
while i * i <= n {
if n % i == 0 {
return false;
}
i += 1;
}
true
}
fn main() {
for n in 1..=20 {
if is_prime(n) {
print!("{} ", n);
}
}
println!(); // 输出: 2 3 5 7 11 13 17 19
}
练习 3:递归阶乘
fn factorial(n: u64) -> u64 {
if n <= 1 {
1
} else {
n * factorial(n - 1)
}
}
fn main() {
for i in 0..=10 {
println!("{}! = {}", i, factorial(i));
}
}
常见错误
1. 返回值加了分号
// ❌ 返回 ()
fn add(a: i32, b: i32) -> i32 {
a + b; // 分号让它变成语句
}
// ✅ 去掉分号
fn add(a: i32, b: i32) -> i32 {
a + b
}
2. 返回类型不匹配
// ❌ 返回 i32 但函数签名是 f64
fn half(x: i32) -> f64 {
x / 2 // 整数除法,结果是 i32
}
// ✅
fn half(x: i32) -> f64 {
x as f64 / 2.0
}
3. 忘记处理返回值
fn get_value() -> i32 { 42 }
fn main() {
get_value(); // ⚠️ 返回值被忽略(编译器警告)
let v = get_value(); // ✅
}
小结
| 要点 | 说明 |
|---|---|
fn name(args) -> Type { ... } | 函数定义 |
| 不加分号 | 表达式,作为返回值 |
| 加分号 | 语句,返回 () |
return | 提前返回(通常用表达式语法) |
(T1, T2) | 元组,用于多返回值 |
-> ! | 永不返回(发散函数) |