控制流和函数是任何编程语言的核心构造块。Rust在这方面有独特的设计——if是表达式、循环有丰富控制、函数支持多种参数模式。本课将深入这些特性。
学习目标:掌握if表达式、各种循环、函数定义与参数、表达式与语句的区别
Rust的if不同于大多数语言——它是表达式,有返回值!
fn main() {
let number = 7;
if number > 10 {
println!("大于10");
} else if number > 5 {
println!("大于5但不大于10");
} else {
println!("5或更小");
}
}
fn main() {
let condition = true;
let number = if condition { 5 } else { 6 };
println!("number = {}", number);
// 实际应用:根据条件选择不同消息
let score = 85;
let grade = if score >= 90 {
"A"
} else if score >= 80 {
"B"
} else if score >= 70 {
"C"
} else if score >= 60 {
"D"
} else {
"F"
};
println!("分数{} -> 等级{}", score, grade);
// ⚠️ 两个分支的类型必须一致!
// let x = if true { 5 } else { "six" }; // ❌ 类型不匹配
}
✅ 验证通过
bool类型,不会像C/JS那样自动转换。if 0 {}会编译错误。
Rust有三种循环:loop、while和for。它们都可以作为表达式使用。
fn main() {
// 基本loop
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // break可以带返回值!
}
};
println!("result = {}", result); // 20
// 循环标签(嵌套循环时用)
let mut count = 0;
'outer: loop {
println!("外层 count = {}", count);
let mut remaining = 10;
loop {
println!(" 内层 remaining = {}", remaining);
if remaining == 9 {
break; // 只跳出内层
}
if count == 2 {
break 'outer; // 跳出外层!
}
remaining -= 1;
}
count += 1;
}
println!("循环结束");
}
✅ 验证通过
fn main() {
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("发射!🚀");
// while遍历数组(不推荐,用for更好)
let arr = [10, 20, 30, 40, 50];
let mut index = 0;
while index < arr.len() {
println!("arr[{}] = {}", index, arr[index]);
index += 1;
}
}
✅ 验证通过
fn main() {
// 遍历数组
let arr = [10, 20, 30, 40, 50];
for element in arr {
println!("元素: {}", element);
}
// 带索引遍历
for (i, &v) in arr.iter().enumerate() {
println!("索引{}: 值{}", i, v);
}
// 范围
for i in 0..5 { // 0,1,2,3,4
print!("{} ", i);
}
println!();
for i in 1..=5 { // 1,2,3,4,5
print!("{} ", i);
}
println!();
// 反向
for i in (1..=5).rev() {
print!("{} ", i);
}
println!();
// 步进(通过迭代器方法)
for i in (0..20).step_by(5) {
print!("{} ", i);
}
println!();
// continue和break
for n in 1..=10 {
if n % 2 == 0 {
continue; // 跳过偶数
}
if n > 7 {
break; // 大于7停止
}
print!("{} ", n);
}
println!();
}
✅ 验证通过
// 无参数无返回值
fn say_hello() {
println!("你好,Rust!");
}
// 有参数和返回值
fn add(a: i32, b: i32) -> i32 {
a + b // 注意:无分号!最后一个表达式就是返回值
}
// 多种返回方式
fn absolute(x: i32) -> i32 {
if x >= 0 {
x // if表达式返回
} else {
-x
}
}
// 提前返回用return
fn factorial(n: u64) -> u64 {
if n <= 1 {
return 1; // 提前返回
}
n * factorial(n - 1) // 递归
}
fn main() {
say_hello();
println!("3 + 5 = {}", add(3, 5));
println!("|−7| = {}", absolute(-7));
println!("5! = {}", factorial(5));
}
✅ 验证通过
a + b(无分号)→ 表达式,有返回值a + b;(有分号)→ 语句,返回();就作为返回值,加了;则返回()
// 可变参数
fn increment(mut x: i32) -> i32 {
x += 1;
x
}
// 引用参数(借用)
fn greet(name: &str) -> String {
format!("你好,{}!", name)
}
// 可变引用
fn append_world(s: &mut String) {
s.push_str(" World");
}
// 默认值?Rust没有默认参数,但可以用Option
fn greet_with_title(name: &str, title: Option<&str>) -> String {
match title {
Some(t) => format!("{}, {}", t, name),
None => format!("{}", name),
}
}
// 切片参数
fn first_word(s: &str) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}
s
}
fn main() {
println!("increment(5) = {}", increment(5));
println!("{}", greet("Rust"));
let mut msg = String::from("Hello");
append_world(&mut msg);
println!("拼接后: {}", msg);
println!("{}", greet_with_title("Alice", Some("Dr.")));
println!("{}", greet_with_title("Bob", None));
let text = String::from("hello world");
println!("第一个词: {}", first_word(&text));
}
✅ 验证通过
fn add(a: i32, b: i32) -> i32 { a + b }
fn multiply(a: i32, b: i32) -> i32 { a * b }
fn apply(f: fn(i32, i32) -> i32, a: i32, b: i32) -> i32 {
f(a, b)
}
fn main() {
// 函数指针
let op: fn(i32, i32) -> i32 = add;
println!("5 + 3 = {}", op(5, 3));
// 作为参数传递
println!("apply(add, 5, 3) = {}", apply(add, 5, 3));
println!("apply(multiply, 5, 3) = {}", apply(multiply, 5, 3));
// 函数存储在集合中
let operations: [fn(i32, i32) -> i32; 3] = [add, multiply, |a, b| a - b];
for (i, op) in operations.iter().enumerate() {
println!("操作{}: apply(10, 3) = {}", i, op(10, 3));
}
}
✅ 验证通过
// 返回never类型(!)的函数——永远不会正常返回
fn panic_if_negative(x: i32) -> i32 {
if x < 0 {
panic!("不能为负数!got {}", x);
}
x
}
// 循环也返回never类型
fn forever() -> ! {
loop {
// 永远不会返回
}
}
fn main() {
let x = 42;
let y = panic_if_negative(x);
println!("y = {}", y);
// panic_if_negative(-1); // 运行时panic!
}
✅ 验证通过
use std::io::{self, Write};
fn get_input(prompt: &str) -> String {
print!("{}", prompt);
io::stdout().flush().unwrap();
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
input.trim().to_string()
}
fn evaluate_guess(secret: i32, guess: i32) -> &'static str {
if guess < secret {
"太小了!"
} else if guess > secret {
"太大了!"
} else {
"猜对了!🎉"
}
}
fn main() {
let secret = 42; // 固定答案,演示用
println!("🎲 猜数字游戏!");
println!("我想了一个1-100之间的数字");
let mut attempts = 0;
loop {
let input = get_input("请输入你的猜测: ");
let guess: i32 = match input.parse() {
Ok(n) => n,
Err(_) => {
println!("请输入有效数字!");
continue;
}
};
attempts += 1;
let result = evaluate_guess(secret, guess);
println!("{}", result);
if guess == secret {
println!("你用了{}次猜对了!", attempts);
break;
}
}
}
编写程序输出1-100:3的倍数输出"Fizz",5的倍数输出"Buzz",15的倍数输出"FizzBuzz",其他输出数字本身。
编写函数fib(n: u32) -> u64返回第n个斐波那契数,用迭代和递归两种方式实现。
用嵌套for循环输出九九乘法表。
编写calculate(op: char, a: f64, b: f64) -> Option<f64>,支持+、-、*、/运算,除0返回None。
🔒 下一课解锁:所有权与借用 —— Rust最独特也最核心的特性
fn main() {
// 函数组合模式
let process = |s: &str| -> String {
s.split_whitespace()
.map(|w| w.to_uppercase())
.filter(|w| w.len() > 2)
.collect::>()
.join(" ")
};
println!("{}", process("hi hello world rust ok"));
// 柯里化模拟
fn make_adder(x: i32) -> impl Fn(i32) -> i32 {
move |y| x + y
}
let add5 = make_adder(5);
println!("5+3 = {}", add5(3));
// 折叠操作
let nums = vec![1, 2, 3, 4, 5];
let product: i32 = nums.iter().fold(1, |acc, &x| acc * x);
println!("5! = {}", product);
// 管道操作
let result = "hello world rust programming"
.split_whitespace()
.map(|w| w.len())
.filter(|&l| l > 3)
.sum::();
println!("长单词字母总数: {}", result);
}
✅ 验证通过
// 普通递归
fn fib_recursive(n: u32) -> u64 {
match n {
0 => 0, 1 => 1,
_ => fib_recursive(n - 1) + fib_recursive(n - 2),
}
}
// 迭代版本(推荐)
fn fib_iterative(n: u32) -> u64 {
let mut a = 0u64;
let mut b = 1u64;
for _ in 0..n {
let temp = a + b;
a = b;
b = temp;
}
a
}
// 累加器递归
fn factorial_tail(n: u64, acc: u64) -> u64 {
if n <= 1 { acc } else { factorial_tail(n - 1, acc * n) }
}
fn main() {
println!("fib_iterative(30) = {}", fib_iterative(30));
println!("fib_iterative(50) = {}", fib_iterative(50));
println!("10! = {}", factorial_tail(10, 1));
// ⚠️ Rust不保证尾调用优化(TCO)
// 深度递归可能导致栈溢出
// 推荐用迭代或显式栈替代
println!("提示:Rust不保证TCO,深度递归请用迭代");
}
✅ 验证通过